Отношения по составным ключам с использованием sqlalchemy - PullRequest
39 голосов
/ 21 сентября 2011

У меня есть эта простая модель 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 Ответ

67 голосов
/ 22 сентября 2011

Проблема в том, что вы определили каждый из зависимых столбцов как внешние ключи отдельно, когда это не совсем то, что вы намерены, вам, конечно, нужен составной внешний ключ. 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__. При этом relationship, определенный в Author.books, работает как раз.

...