SQLAlchemy:表有多个外键约束关系
Posted
技术标签:
【中文标题】SQLAlchemy:表有多个外键约束关系【英文标题】:SQLAlchemy: tables have more than one foreign key constraint relationship 【发布时间】:2021-07-10 08:37:17 【问题描述】:我正在开发一个新的学校管理数据库。我现在使用 mysql 已经很长时间了,但我对 python 和 sqlalchemy 还是很陌生。首先我设计了(巨型)数据库,然后使用flask-sqlacodegen生成了类...... 问题: 我有两张桌子:人员和工作人员。面对面,所有人都被存储,每个数据集都有一个 mod_user。在员工中,仅存储公司员工。 mod_user 必须是员工...
这是我的员工/个人课程:
#connect_test.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://XXX:XXX@localhost/schooldb_model'
db = SQLAlchemy(app)
class TPerson(db.Model):
__tablename__ = 't_person'
idt_person = db.Column(db.Integer, primary_key=True, info='ID der Person')
salutation = db.Column(db.String(10), nullable=False, server_default=db.FetchedValue(),
info='Anrede - Geschlecht der Person ist daraus ersichtlich')
firstname = db.Column(db.String(45), nullable=False, server_default=db.FetchedValue(), info='Vorname')
lastname = db.Column(db.String(45), nullable=False, server_default=db.FetchedValue(), info='Nachname')
birthdate = db.Column(db.Date, info='Geburtsdatum - wird 1900-01-01 gesetzt wenn nicht bekannt')
birthplace = db.Column(db.String(45), info='Geburtsort')
cityzenship = db.Column(db.String(45), nullable=False, server_default=db.FetchedValue(), info='Staatsbürgerschaft')
familystatus = db.Column(db.String(30), nullable=False, server_default=db.FetchedValue())
dmtx_idt = db.Column(db.LargeBinary)
qr_idt = db.Column(db.LargeBinary)
mod_timestamp = db.Column(db.DateTime, nullable=False, index=True, server_default=db.FetchedValue(),
info='Timestamp of modification')
mod_user = db.Column(db.ForeignKey('t_staff.t_person_idt_person'), nullable=False, index=True)
t_staff = db.relationship('TStaff', primaryjoin='TPerson.mod_user == TStaff.t_person_idt_person',
backref='t_people')
#mod_user = db.Column(db.Integer, nullable=False, index=True, server_default=db.FetchedValue())
class TStaff(TPerson):
__tablename__ = 't_staff'
t_person_idt_person = db.Column(db.ForeignKey('t_person.idt_person'), primary_key=True, info='Person id')
begin = db.Column(db.Date, nullable=False, info='Ist Mitarbeitr seit.')
end = db.Column(db.Date, info='War Mitarbeiter bis.')
从 python 控制台运行代码
>>> from connect_test import TPerson
结果是:
sqlalchemy.exc.AmbiguousForeignKeysError: Can't determine join between 't_person' and 't_staff'; tables have more than one foreign key constraint relationship between them. Please specify the 'onclause' of this join explicitly.
我知道,在这种特殊情况下,我真的不需要 mod_users 外键约束 - 删除它并执行 mod_user = db.Column(db.Integer, nullable=False, index=True, server_default=db.FetchedValue())
工作正常。
但是我在数据库的其余部分有数百个我无法删除的其他约束 - 所以我希望轻松解决这个问题?案例将帮助我了解其余的...
问候,c。
【问题讨论】:
欢迎来到 SO!感谢您提供一个最小的示例。也许this answer 有帮助,即将 mapper_args = 'polymorphic_identity': 'manager', 'inherit_condition': TPerson.mod_user == t_person_idt_person 添加到您的 TStaff 类中。 但是为什么 TStaff 中的注释行不起作用?person = db.relationship('TPerson', primaryjoin='TPerson.idt_person == TStaff.t_person_idt_person', backref='staff')
不应该做同样的事情吗?
【参考方案1】:
@above_c_level:非常感谢! - 有用。只好改变条件。 完整代码如下:
class TPerson(db.Model):
__tablename__ = 't_person'
idt_person = db.Column(db.Integer, primary_key=True, info='ID der Person')
salutation = db.Column(db.String(10), nullable=False, server_default=db.FetchedValue(),
info='Anrede - Geschlecht der Person ist daraus ersichtlich')
firstname = db.Column(db.String(45), nullable=False, server_default=db.FetchedValue(), info='Vorname')
lastname = db.Column(db.String(45), nullable=False, server_default=db.FetchedValue(), info='Nachname')
birthdate = db.Column(db.Date, info='Geburtsdatum - wird 1900-01-01 gesetzt wenn nicht bekannt')
birthplace = db.Column(db.String(45), info='Geburtsort')
cityzenship = db.Column(db.String(45), nullable=False, server_default=db.FetchedValue(), info='Staatsbürgerschaft')
familystatus = db.Column(db.String(30), nullable=False, server_default=db.FetchedValue())
dmtx_idt = db.Column(db.LargeBinary)
qr_idt = db.Column(db.LargeBinary)
mod_timestamp = db.Column(db.DateTime, nullable=False, index=True, server_default=db.FetchedValue(),
info='Timestamp of modification')
mod_user = db.Column(db.ForeignKey('t_staff.t_person_idt_person'), nullable=False, index=True)
t_staff = db.relationship('TStaff', primaryjoin='TPerson.mod_user == TStaff.t_person_idt_person',
backref='people')
class TStaff(TPerson):
__tablename__ = 't_staff'
t_person_idt_person = db.Column(db.ForeignKey('t_person.idt_person'), primary_key=True, info='Person id')
begin = db.Column(db.Date, nullable=False, info='Ist Mitarbeitr seit.')
end = db.Column(db.Date, info='War Mitarbeiter bis.')
# person = db.relationship('TPerson', primaryjoin='TPerson.idt_person == TStaff.t_person_idt_person',
# backref='staff')
__mapper_args__ = 'polymorphic_identity': 'staff',
'inherit_condition': TPerson.idt_person == t_person_idt_person
【讨论】:
以上是关于SQLAlchemy:表有多个外键约束关系的主要内容,如果未能解决你的问题,请参考以下文章