53 lines
1.9 KiB
Python
53 lines
1.9 KiB
Python
"""
|
|
Position ORM model - Time series data
|
|
"""
|
|
from sqlalchemy import Column, String, TIMESTAMP, BigInteger, Float, ForeignKey, CheckConstraint, Index
|
|
from sqlalchemy.sql import func
|
|
from sqlalchemy.orm import relationship
|
|
from app.database import Base
|
|
|
|
|
|
class Position(Base):
|
|
"""Celestial body position history"""
|
|
|
|
__tablename__ = "positions"
|
|
|
|
id = Column(BigInteger, primary_key=True, autoincrement=True)
|
|
body_id = Column(
|
|
String(50),
|
|
ForeignKey("celestial_bodies.id", ondelete="CASCADE"),
|
|
nullable=False,
|
|
comment="Reference to celestial_bodies.id",
|
|
)
|
|
time = Column(TIMESTAMP, nullable=False, comment="Position timestamp (UTC)")
|
|
x = Column(Float, nullable=False, comment="X coordinate (AU)")
|
|
y = Column(Float, nullable=False, comment="Y coordinate (AU)")
|
|
z = Column(Float, nullable=False, comment="Z coordinate (AU)")
|
|
vx = Column(Float, nullable=True, comment="X velocity (optional)")
|
|
vy = Column(Float, nullable=True, comment="Y velocity (optional)")
|
|
vz = Column(Float, nullable=True, comment="Z velocity (optional)")
|
|
source = Column(
|
|
String(50),
|
|
nullable=False,
|
|
default="nasa_horizons",
|
|
comment="Data source",
|
|
)
|
|
created_at = Column(TIMESTAMP, server_default=func.now())
|
|
|
|
# Relationship
|
|
body = relationship("CelestialBody", back_populates="positions")
|
|
|
|
# Constraints and indexes
|
|
__table_args__ = (
|
|
CheckConstraint(
|
|
"source IN ('nasa_horizons', 'calculated', 'user_defined', 'imported')",
|
|
name="chk_source",
|
|
),
|
|
Index("idx_positions_body_time", "body_id", "time", postgresql_using="btree"),
|
|
Index("idx_positions_time", "time"),
|
|
Index("idx_positions_body_id", "body_id"),
|
|
)
|
|
|
|
def __repr__(self):
|
|
return f"<Position(body_id='{self.body_id}', time='{self.time}', x={self.x}, y={self.y}, z={self.z})>"
|