Estoy oxidado en SQL y completamente nuevo en SQL Alchemy, pero tengo un próximo proyecto que usa ambos. Así que pensé en escribir algo para estar cómodo. Sufriendo de una resaca, decidí escribir algo para hacer un seguimiento de los niveles de alcohol.¿Cómo modelo una relación de varios a varios en 3 tablas en SQLAlchemy (ORM)?
que tienen events
donde users
participar y consumen drinks
. Esas son mis tres tablas básicas (con una tabla auxiliar guestlist
, para una relación m: n entre usuarios y eventos).
bebidas lista de las bebidas disponibles en todos los eventos a todos los usuarios todo el tiempo (sin necesidad de direccionar nada). usuarios se crean de vez en cuando, por lo que son eventos. todos los usuarios pueden unirse a todos los eventos , entonces uso la tabla guestlist
para mapearlos.
Ahora en el corazón de la pregunta: Necesito hacer un seguimiento de a qué hora consume el usuario qué bebida en qué evento. Trato de resolver esto con otra tabla shots
(ver a continuación), pero no estoy seguro de si esta es una buena solución.
ERP Diagram http://s1.anyimg.com/img/g6ld1ku/Bildschirmfoto.png
En SQL Alchemy podría parecer algo como esto (o no, pero esto es lo que se me ocurrió hasta ahora) ::
guestlist_table = Table('guestlist', Base.metadata,
Column('event_id', Integer, ForeignKey('events.id')),
Column('user_id', Integer, ForeignKey('users.id'))
)
class Event(Base):
__tablename__ = 'events'
id = Column(Integer, primary_key=True)
name = Column(String(80), nullable=False)
started = Column(DateTime, nullable=False, index=True,
default=datetime.datetime.now
)
users = relationship("User", secondary=guestlist_table, backref="events")
# ...
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False, unique=True, index=True)
birthdate = Column(Date, nullable=False)
weight = Column(Integer, nullable=False)
sex = Column(Boolean, nullable=False)
# ...
class Drink(Base):
__tablename__ = 'drinks'
id = Column(Integer, primary_key=True)
name = Column(String(50), nullable=False)
volume = Column(Numeric(5,2), nullable=False)
percent = Column(Numeric(5,2), nullable=False)
# ...
class Shots(Base):
__tablename__ = 'shots'
id = Column(Integer, primary_key=True)
at = Column(DateTime, nullable=False,
default=datetime.datetime.now
)
user_id = Column(Integer, ForeignKey('users.id'), index=True)
event_id = Column(Integer, ForeignKey('events.id'), index=True)
drink_id = Column(Integer, ForeignKey('drinks.id'))
user = relationship("User", backref="shots")
event = relationship("Event", backref="shots")
drink = relationship("Drink", uselist=False) # one-to-one, no backref needed
Me esfuerzo por encontrar una buena manera de construir una tabla que asigna eventos, usuarios y bebidas juntos: Cómo debo formular la relationships y cómo hacer yo query es?
La cosa es que siento que he pasado por alto algo. Y, francamente, estoy absolutamente perdido en cómo consulta?
Estas son las preguntas que haría que la mayoría de las veces:
- yo por lo menos necesito para obtener todos los tiros que se consumen en un caso (probablemente ordenados por el usuario)
- También a veces necesito todos los tiros para un usuario específico (probablemente ordenado por evento)
- Y un montón de conteo:
- Número de disparos por evento
- Número de disparos por u Ser
- Número de disparos bebió un usuario en un evento
es la tabla shots
una manera aceptable para manejar esto?
Hola @Brutus, según mi opinión, tu relación es como 1 usuario puede participar en muchos eventos y 1 evento tiene muchos usuarios (guestlist). 1 evento tiene muchas bebidas y 1 bebida puede servir en muchos eventos (lista de bebidas). 1 usuario puede tomar muchas bebidas y 1 bebida puede servir a muchos usuarios (guestdrinklist). ¿Es esto correcto? – Nilesh
Todas las bebidas están disponibles en todos los eventos, así que pensé que podría no necesitar 'drinklist'. Lo que llamas 'guestdrinklist' traté de modelar en la clase' Shots'. ¿Sería mejor dividir la clase en dos tablas? – Brutus
Si todas las bebidas están disponibles en todos los eventos, entonces no es necesario especificar la relación entre bebidas y eventos.Debe especificar la relación si el subconjunto de su campo está asociado con otra entidad si todo está asociado, entonces no se necesita relación. Puede crear una relación entre bebidas y usuario. – Nilesh