如何为具有复合主键的表构建外键?
Posted
技术标签:
【中文标题】如何为具有复合主键的表构建外键?【英文标题】:How Can I Build a ForeignKey to a Table Which Has Composite Primary Key? 【发布时间】:2013-03-07 00:22:30 【问题描述】:我在弄清楚如何为我正在定义的表正确构建我的 ForeignKey 列时遇到了很多麻烦。我在这里概述了我的模型(并在我的 PhoneNumber 模型中有问题的行旁边添加了注释):
class AreaCode(db.Model):
__tablename__ = 'areacodes'
area_code = db.Column(db.Integer, primary_key=True)
exchanges = db.relationship('Exchanges', backref='area_code')
class Exchange(db.Model):
__tablename__ = 'exchanges'
exchange = db.Column(db.Integer, primary_key=True)
area_code_pk = db.Column(db.Integer, db.ForeignKey('areacodes.area_code'), primary_key=True)
class PhoneNumber(db.Model):
__tablename__ = 'phonenumbers'
phone_number = db.Column(db.Numeric(precision=4, scale=0), primary_key=True)
exchange_pk = db.Column(db.Integer, db.ForeignKey('exchanges.exchange'), primary_key=True) # this doesnt work since Exchange has two primary keys
这是发生了什么:
我的 Exchange 表有一个复合主键。这是我的用例所必需的。
我试图定义的 PhoneNumber 表需要 Exchange 表的 ForeignKey,但由于 Exchange 表有一个复合主键,我不知道如何使关系起作用。
任何指导将不胜感激。谢谢。
【问题讨论】:
在您的示例中,Exchange 只有一个主键?exchange
列是否也应为 primary=True
?
几个值得看的东西:docs.sqlalchemy.org/en/latest/core/…***.com/questions/10525797/… 还有,你用的是什么数据库?
嗨@shazow,你是对的,我在那里打错字了。 Exchange 有两个主键。另外,我使用的是 PostgreSQL 9.2。
你能解释一下“无法弄清楚如何让这种关系发挥作用”的意思吗?你试过什么?您是否在Relationship
中指定了foreign_keys
?或者,您可以指定 primaryjoin
条件。
@rdegges:我已经编辑了关于术语的问题。
【参考方案1】:
因此,在与 sqlalchemy 邮件列表中的几位伟人交谈后,我终于解决了上述问题。下面是我的代码的最终版本,它允许我在表之间正确关联:
class AreaCode(db.Model):
__tablename__ = 'areacodes'
area_code = db.Column(db.Integer, primary_key=True)
class Exchange(db.Model):
__tablename__ = 'exchanges'
exchange = db.Column(db.Integer, primary_key=True)
area_code_pk = db.Column(db.Integer, db.ForeignKey('areacodes.area_code'),
primary_key=True)
area_code = db.relationship('AreaCode', backref=db.backref('exchanges', lazy='dynamic'))
class PhoneNumber(db.Model):
__tablename__ = 'phonenumbers'
__table_args__ = (
db.ForeignKeyConstraint(
['exchange_exchange', 'exchange_area_code_pk'],
['exchanges.exchange', 'exchanges.area_code_pk'],
),
)
phone_number = db.Column(db.Integer, primary_key=True)
exchange_exchange = db.Column(db.Integer, primary_key=True)
exchange_area_code_pk = db.Column(db.Integer, primary_key=True)
exchange = db.relationship('Exchange', backref=db.backref('phone_numbers', lazy='dynamic'))
【讨论】:
当您与 SQL Alchemy 人员聊天时,他们是否指定了为什么要在表上设置外键约束以及为什么不直接在exchange_exchange
和 exchange_area_code_pk
两列上执行此操作?
不幸的是,@Carel,这是我大约 7 年前写的代码,老实说我不确定。我尝试通过我的收件箱进行搜索,但无法找到该线程——我怀疑它是在我现在无法访问的另一个电子邮件提供商上。对不起:(
感谢您付出了这么多努力@rdeggas,我真的很感激。我再次查看了 SQL Alchemy documentation,它指出这是在两个表之间设置复合外键的唯一方法。 Andrei Vacariu 现在也有一篇文章对此进行了深入探讨以上是关于如何为具有复合主键的表构建外键?的主要内容,如果未能解决你的问题,请参考以下文章