J'ai ce modèle simple de Author - Books et je ne peux pas trouver un moyen de faire de firstName et lastName une clé composite et de l'utiliser en relation. Des idées?
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'))
Le problème est que vous avez défini chacune des colonnes dépendantes comme des clés étrangères séparément, alors que ce n'est pas vraiment ce que vous voulez, vous voulez bien sûr une clé étrangère composite. Sqlalchemy répond à cela en disant (de manière peu claire) qu'il ne peut pas deviner quelle clé étrangère utiliser (firstName
ou lastName
).
La solution, déclarant une clé étrangère composite, est un peu maladroite en déclarative, mais toujours assez évidente:
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]),
{})
L'important ici est que les définitions ForeignKey
ont disparu des colonnes individuelles et qu'un ForeignKeyConstraint
est ajouté à un __table_args__
variable de classe. Avec cela, le relationship
défini sur Author.books
fonctionne parfaitement.