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