cosmo_backend/app/models/db/position.py

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})>"