使用sqlalchemy的复合键的关系

时间:2011-09-21 18:27:28

标签: python sqlalchemy key composite database-relations

我有这个简单的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'))            

1 个答案:

答案 0 :(得分:63)

问题是你已经将每个依赖列分别定义为外键,当这不是你想要的时候,你当然需要一个复合外键。 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__类变量中。这样,relationship上定义的Author.books工作正常。