sqlalchemy,怎么针对复合主键建立复合外键?

我在使用sqlalchemy操作sqlite3数据库。
我有两张表,每张表有两个主键,作为复合主键。我想要对这两张表建立一对一的关系。

报错:

Could not determine join condition between parent/child tables on relationship Parent.child_info - there are multiple foreign key paths linking the tables.  Specify the 'foreign_keys' argument, providing a list of those columns which should be counted as containing a foreign key reference to the parent table.

父类和子类的结构如下:

class Parent(Base):
    __tablename__ = "parents"

    device = Column(Integer, primary_key=True)
    reg = Column(Integer, primary_key=True)
    ...

    child_info = relationship(
        'Chlidren', back_populates='parent_info', uselist=False)

    def __repr__(self) -> str:
        ...


class Chlidren(Base):
    __tablename__ = "childs"

    ca = Column(Integer, primary_key=True)
    ioa = Column(Integer, primary_key=True)
    ...

    parent_device = Column(Integer, ForeignKey('parents.device'))
    parent_reg = Column(Integer, ForeignKey('parents.reg'))
    parent_info = relationship(
        'Parent', back_populates='child_info')

按照错误的提示,需要在relationship函数指定foreign_keys参数。
尝试过在Children类中通过relationship,定义两个属性分别对应parent_device、parent_reg。还是原来的报错。
我不知道怎么正确地修改以解决这个问题。
我知道如果我不使用复合主键,可以解决这个问题。

在保留两张表的复合主键的情况下,怎么解决这个问题?

关于这种写法中两个class的主键是否是复合主键:
这是parents的DDL:

CREATE TABLE parents (
    device INTEGER NOT NULL, 
    reg INTEGER NOT NULL, 
    PRIMARY KEY (device, reg)
)

这是子表的DDL:

CREATE TABLE childs (
    ca INTEGER NOT NULL, 
    ioa INTEGER NOT NULL, 
    parent_device_id INTEGER, 
    parent_reg_id INTEGER, 
    PRIMARY KEY (ca, ioa), 
    FOREIGN KEY(parent_device_id) REFERENCES parents (device), 
    FOREIGN KEY(parent_reg_id) REFERENCES parents (reg)
)

我想子表正确的DDL应该是
FOREIGN KEY(parent_device_id, parent_reg_id) REFERENCES parents (device, reg)
那么,sqlalchemy要怎么写才能生产这样的sql?

阅读 2.5k
2 个回答
    ForeignKeyConstraint([parent_device, parent_reg], [
                         'parents.device', 'parents.reg'])
class Table
 relationship(lambda: Role, secondary=lambda: RoleChild.__table__,
              primaryjoin=lambda: Role.id == RoleChild.parent_role,
              foreign_keys=lambda: [RoleChild.parent_role, RoleChild.child_role])

另外, 你这个不是复合主键, 是两个主键, 用哪个都可以.

关联条件, 外键, 都要声明.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏