web-dev-qa-db-ja.com

sqlalchemyを使用した複合キーの関係

私はこのAuthor-Booksの単純なモデルを持っていますが、firstNameとlastNameを複合キーにして、それを関連して使用する方法を見つけることができません。何か案は?

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:pass@library')
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'))            
44
mdob

問題は、従属列をそれぞれ個別に外部キーとして定義したことです。それが本当に意図したものではない場合は、もちろん複合外部キーが必要です。 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の定義が個々の列から削除され、ForeignKeyConstraint__table_args__クラス変数に追加されることです。これにより、Author.booksで定義されたrelationshipが正しく機能します。