2016-02-04 55 views
3

我有一個多客戶平臺,可以有多個標籤的人,並讓一個帶有一個標籤的foo對象。我不希望每個客戶的用戶與其他客戶分享他們的聯繫人(個人)或標籤或foo。每個客戶的每個標籤名稱都是唯一的帶複合鍵的sqlalchemy輔助表

我怎麼能對標籤(名稱,CUSTOMER_NAME)一複合鍵和人員之間的N-M的關係和標籤

我嘗試這樣做:

enter image description here

person_label_table = Table('person_label', Base.metadata, 
         Column('person_id', Integer, ForeignKey('person.id'), primary_key=True), 
         Column('name', Unicode(32), ForeignKey('label.name'), primary_key=True), 
         Column('customer_name', String(32), ForeignKey('label.customer_name'), primary_key=True) 
         ) 

class Person(Base, SaveMixin): 
    __tablename__ = 'person' 
    id = Column(Integer, primary_key=True) 
    labels = relationship('Label', secondary=person_label_table) 

class Label(Base, SaveMixin): 
    __tablename__ = 'label' 
    name = Column(Unicode(32), primary_key=True) 
    customer_name = Column(String(32), ForeignKey('customer.name'), primary_key=True) 
    color = Column(String(32)) 

但我有此錯誤:

sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 'label' and 'person_label'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly. 

我也試圖與一個更經典的鏈接表person_label(label_id,爲person_id)和添加一個標籤的標籤,但標籤ID的必須加載到前臺網絡,當我做session.merge()與標籤(沒有ID)我有:

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: label.name, label.customer_name [SQL: 'INSERT INTO label (name, customer_name, color) VALUES (?, ?, ?)'] [parameters: ('foo', 'bar', 'grey')] 

所以你會如何處理這種情況?

謝謝你的時間。


編輯: 萬一它可以幫助時,布倫丹·阿貝爾響應,並顯示代碼後,我有這個錯誤:

sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition between parent/child tables on relationship Person.labels - there are multiple foreign key paths linking the tables via secondary table 'person_label'. Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference from the secondary table to each of the parent and child tables. 

,所以我改變的定義標籤親自:

labels = relationship('Label', secondary=person_label_table, foreign_keys=[id]): 

但我當時:

sqlalchemy.exc.NoForeignKeysError: Could not determine join condition between parent/child tables on relationship Person.labels - there are no foreign keys linking these tables via secondary table 'person_label'. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify 'primaryjoin' and 'secondaryjoin' expressions. 

我結束了(上添加人primaryjoin/secondaryjoin和消除對複合鍵的ForeignKey的):

class Person(Base, SaveMixin): 
    __tablename__ = 'person' 
    labels = relationship('Label', secondary=person_label_table, 
         primaryjoin='and_(Person.id == person_label.c.person_id)', 
         secondaryjoin='and_(person_label.c.name == Label.name, person_label.c.customer_name == Label.customer_name)') 

person_label_table = Table('person_label', Base.metadata, 
         Column('person_id', Integer, ForeignKey('person.id'), primary_key=True), 
         Column('name', Unicode(32), primary_key=True), 
         Column('customer_name', String(32), primary_key=True), 
         ForeignKeyConstraint(['name', 'customer_name'], ['label.name', 'label.customer_name']) 
         ) 

回答

2

你必須明確地表明,在使用一個ForeignKeyConstraint的複合關係:

person_label_table = Table('person_label', Base.metadata, 
    Column('person_id', Integer, ForeignKey('person.id'), primary_key=True), 
    Column('name', Unicode(32), primary_key=True), 
    Column('customer_name', String(32), primary_key=True), 
    ForeignKeyConstraint(['name', 'customer_name'], ['label.name', 'label.customer_name']) 
) 

docs提供了一些這方面的例子。

It’s important to note that the ForeignKeyConstraint is the only way to define a composite foreign key. While we could also have placed individual ForeignKey objects on both the invoice_item.invoice_id and invoice_item.ref_num columns, SQLAlchemy would not be aware that these two values should be paired together - it would be two individual foreign key constraints instead of a single composite foreign key referencing two columns.