2011-09-21 10 views
30

私はこの簡単なAuthor-Booksモデルを持っており、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は、(非常に明確な方法ではなく)使用する外部キー(firstNameまたはlastName)を推測できないと言ってこれに応答しています。複合外部キーを宣言

ソリューション、宣言型で不格好少しですが、それでもかなり明白:

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定義は、個々の列、およびAからなくなっているということですForeignKeyConstraintがクラス変数__table_args__に追加されます。これにより、Author.booksに定義されているrelationshipが正しく機能します。

+2

[docs](http://docs.sqlalchemy.org/en/rel_0_9/core/constraints.html?highlight=check#metadata-foreignkeys)には、説明と例が追加されています。「ForeignKeyConstraint 'は、複合外部キーを定義する唯一の方法です。 [Foreign]オブジェクトを両方の[...]列に配置することもできますが、SQLAlchemyはこれらの2つの値をペアにする必要があることに気付かず、単一の複合外部キーではなく2つの個別の外部キー制約になります2つの列。 – iled

関連する問題