当前位置: 首页 > 面试题库 >

sqlalchemy:创建关系,但在数据库中没有外键约束?

鲍鸿波
2023-03-14
问题内容

由于sqlalchemy.orm.relationship()已经暗示了该关系,因此我不想在db中创建约束。我该怎么办?

目前,我在进行Alembic迁移后手动删除这些约束。


问题答案:

无需定义“模式”级别ForeignKey约束,而是创建自定义的外部条件;将您要用作“外键”的列以及primaryjoin传递给relationship。您必须手动定义primaryjoin原因,因为:

默认情况下,此值是基于父表和子表(或关联表)的外键关系计算的。

In [2]: class A(Base):
   ...:     a_id = Column(Integer, primary_key=True)
   ...:     __tablename__ = 'a'
   ...:

In [3]: class C(Base):
   ...:     c_id = Column(Integer, primary_key=True)
   ...:     a_id = Column(Integer)
   ...:     __tablename__ = 'c'
   ...:     a = relationship('A', foreign_keys=[a_id],
   ...:                      primaryjoin='A.a_id == C.a_id')
   ...:

外键也可以在primaryjoinusing中内联注释foreign()

a = relationship('A', primaryjoin='foreign(C.a_id) == A.a_id')

您可以验证没有FOREIGN KEY为表 c 发出约束:

In [4]: from sqlalchemy.schema import CreateTable

In [5]: print(CreateTable(A.__table__))

CREATE TABLE a (
        a_id INTEGER NOT NULL, 
        PRIMARY KEY (a_id)
)



In [6]: print(CreateTable(C.__table__))

CREATE TABLE c (
        c_id INTEGER NOT NULL, 
        a_id INTEGER, 
        PRIMARY KEY (c_id)
)

警告:

请注意,FOREIGN KEY在数据库端没有适当的约束,您可以以任何所需的方式将参照完整性破坏成碎片。在ORM
/应用程序级别存在关系,但是不能在数据库中强制执行。



 类似资料:
  • 问题内容: 我有一个用户表和一个朋友表。朋友表拥有两个外键,分别指向我的用户表和状态字段。我试图能够从Friend对象上的User表中调用属性。例如,我希望能够执行诸如friend.name或friend.email之类的操作。 当我得到对象时,我所拥有的只是2,并且我想显示每个用户的所有属性,以便可以在表单等中使用该信息。我对sqlalchemy还是陌生的- 仍在尝试学习更高级的功能。这只是一个

  • 我试图在laravel中创建一个主键-外键关系,但我一直遇到这个错误 我似乎找不到哪里出错了,因为我在查看了SO上的其他答案后,对模式进行了更改。 当我运行时,上面的错误会弹出,这是一个部分迁移。 任何指向这将是真棒,因为我已经寻找了一段时间的解决方案! 谢谢 员工表 部门表 工资表 新增:DB播种机。 根据评论更改了DB种子程序

  • 问题内容: 我有两个表,和。应该是不言自明的,并且包含所有变量的所有可能选择。 有一个外键,指出了它是哪个变量的选项。有一个外键,指出了当前选择的选项。 我用得到周围的循环关系上,并在“关系。但是,我想添加一个额外的数据库约束,以确保该约束是有效的(即,它所指的是一个引用它的选项)。 我需要的逻辑(假设它代表表中的一行)基本上是: 但是我不知道如何使用SQL,声明式或任何其他方法来构造这种约束。如

  • 我目前正在努力理解为什么第一个MySQL代码不能用于position外键。同时,当我添加backtick来定位时,它允许创建表。 我搜索过Position是否是MySQL的保留词,但没有找到任何提到它是保留词的地方。 所以我想知道有没有人知道为什么它不起作用。

  • 但是,我似乎搞错了一些事情,因为当Hibernate创建表时,会创建多个外键,如下所示: 信息:HHH10001501:从JdbcConnectionAccess[org.hibernate.engine.jdbc.env.internal.jdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@5E5595F3]获得的用于(

  • 我在创建mysql数据库中现有表的外键时遇到了一些问题。 我不想创建一个名为的新表来引用它,使用以下方法: 但我发现了错误: 为了获得更多的信息,我做了: 在我看来,这两个列的类型似乎是匹配的,因为它们都是varchar(45)。(我还尝试将列设置为not null,但这没有解决问题)所以我猜问题一定是。但我不太清楚这意味着什么,也不知道如何检查/修复它。有人有什么建议吗?是什么意思?