2012-04-03 43 views
7

我在SQL中很生疏,並且對於SQL Alchemy是全新的,但是有一個即將使用的項目。所以我想我寫了一些東西讓自己舒服。患有宿醉後,我決定寫些東西來跟蹤酒精濃度。如何建模SQLAlchemy(ORM)中的3個表的多對多關係?

events其中users參與和消費drinks。這些是我的三個基本表(有一個幫助表guestlist,對於用戶事件之間的m:n關係)。

飲料名單可在各事件所有用戶所有的時間(無需任何映射)的飲料。 用戶是不時創建的,所以事件。所有用戶都可以加入所有事件,因此我使用guestlist表來映射這些事件。

現在到這個問題的核心:我需要跟蹤哪個用戶在哪個時間喝哪些飲料。我試圖解決這個惠特另一個表shots(見下文),但我不知道這是一個很好的解決方案。

ERP Diagram http://s1.anyimg.com/img/g6ld1ku/Bildschirmfoto.png

SQL Alchemy它可能看起來有點像這個(或沒有,但是這是我想出了迄今爲止)::

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 

我很難找到建立一個好辦法映射事件用戶飲料在一起的表:我應該如何制定relationships和我怎麼query呢?

事情是我有點覺得我忽略了一些東西。 坦白說我絕對失去了如何查詢呢?

這裏是我會做的大部分時間查詢:

  • 我至少需要得到消耗在事件中的所有鏡頭(可能是用戶排序)
  • 我有時也需要所有鏡頭爲特定用戶(可能是事件排序)
  • 和很多計數:
    • 每個事件的拍攝張數
    • 每U拍攝張數SER
    • 拍攝張數,用戶被擊倒在事件

是在shots表來管理這個行不行呢?

+0

你好@Brutus,根據我的觀點,你的關係就像1個用戶可以參與許多事件,1個事件有許多用戶(訪客列表)。 1事件有許多飲料和1飲料可以在許多事件(喝酒單)服務。 1名用戶可以喝很多飲料,1杯飲品可以服務於許多用戶(guestdrinklist)。它是否正確? – Nilesh 2012-04-04 05:05:25

+0

所有飲料都適用於所有活動,所以我想我可能不需要'drinklist'。你所謂的'guestdrinklist'我試圖在'Shots'類中建模。將課堂分成兩張桌子會更好嗎? – Brutus 2012-04-04 13:05:42

+0

如果所有活動都提供所有飲料,則無需指定飲料和活動之間的關係。如果所有關聯的字段的子集與其他實體關聯,那麼您必須指定關係,那麼不需要任何關係。您可以創建飲料和用戶之間的關係。 – Nilesh 2012-04-04 13:14:30

回答

5

我建議你畫一個實體關係圖,這對人們和你理解你的問題會更加清楚。

要回答你的問題:

我至少需要獲得消費上的事件(可能由用戶排序)

要獲得事件的所有鏡頭,您可以將所有鏡頭嘗試

session.query(Shots).filter_by(event_id=event_id) 

event_id是您想要查詢的事件的ID。按用戶存儲,您可以試用

from sqlalchemy.sql.expression import desc, asc 
session.query(Shots) \ 
    .filter_by(event_id=event_id) \ 
    .order_by(asc(Shots.user_id)) 

當然,您可能想按用戶的屬性排序,您可以加入用戶表。

from sqlalchemy.sql.expression import desc, asc 
session.query(Shots) \ 
    .filter_by(event_id=event_id) \ 
    .join(User) \ 
    .order_by(asc(User.name)) 

很容易。

我有時也需要爲特定用戶(可能是事件排序)

就像前面的例子中的所有鏡頭

每個事件

session.query(Shots) \ 
    .filter_by(event_id=event_id) \ 
    .count() 
拍攝張數

我沒有跑他們,我只是在這裏寫他們,但他們如果我沒有輸錯,應該都可以工作。

+0

謝謝你的回答。我一回家就嘗試一下。我還添加了一個ERP。關於我的表格佈局:在給出我的查詢案例的情況下,您是否認爲'shot'表格是將數據映射到一起的有效方法?或者我應該使用另一種方法來組織表格和關係? – Brutus 2012-04-04 15:29:00

相關問題