2011-09-21 69 views
30

我有這個簡單的作者 - 書籍模型,並找不到一種方法,使firstName和lastName複合鍵,並在關係中使用它。有任何想法嗎?使用sqlalchemy複合鍵的關係

from sqlalchemy import create_engine, ForeignKey, Column, String, Integer 
from sqlalchemy.orm import relationship, sessionmaker 
from sqlalchemy.ext.declarative import declarative_base 

Base = declarative_base() 
engine = create_engine('mssql://user:[email protected]') 
engine.echo = True 
session = sessionmaker(engine)() 

class Author(Base): 
    __tablename__ = 'authors' 
    firstName = Column(String(20), primary_key=True) 
    lastName = Column(String(20), primary_key=True) 
    books = relationship('Book', backref='author') 

class Book(Base): 
    __tablename__ = 'books' 
    title = Column(String(20), primary_key=True) 
    author_firstName = Column(String(20), ForeignKey('authors.firstName')) 
    author_lastName = Column(String(20), ForeignKey('authors.lastName'))    

回答

52

的問題是,您已經定義每個因列作爲單獨的外鍵,當這不是真的你想什麼,你當然希望有一個複合外鍵。 Sqlalchemy迴應說(不是很清楚的方式),它不能猜測使用哪個外鍵(firstNamelastName)。

的解決方案,宣告複合外鍵,是一點點笨重的聲明,但仍相當明顯:

class Book(Base): 
    __tablename__ = 'books' 
    title = Column(String(20), primary_key=True) 
    author_firstName = Column(String(20)) 
    author_lastName = Column(String(20)) 
    __table_args__ = (ForeignKeyConstraint([author_firstName, author_lastName], 
              [Author.firstName, Author.lastName]), 
         {}) 

這裏最重要的是,ForeignKey定義從單獨列了,和ForeignKeyConstraint被添加到__table_args__類變量。有了這個,在Author.books上定義的relationship工作正常。

+2

[docs](http://docs.sqlalchemy.org/en/rel_0_9/core/constraints.html?highlight=check#metadata-foreignkeys)包含額外的說明和示例:重要的是要注意'ForeignKeyConstraint '是定義複合外鍵的唯一方法。雖然我們也可以在兩個列上放置單獨的ForeignKey對象,但SQLAlchemy不會意識到這兩個值應該配對在一起 - 這將是兩個單獨的外鍵約束,而不是單個複合外鍵引用兩列。 – iled