SQLAlchemy 外键允许为空

Posted

技术标签:

【中文标题】SQLAlchemy 外键允许为空【英文标题】:SQLAlchemy Foreign Key allow null 【发布时间】:2021-12-30 10:35:28 【问题描述】:

我正在尝试创建一个允许在不同上下文中上传 pdf 数据的数据库。所以我有一个包含网站的表格,以及一个包含来自该网站的 pdf 数据的表格。所以很自然,我应该有一些将两者联系起来的 FK,我确实做到了。

但是,在使用 pdf 数据的同一张表中,我希望能够只给它一个未附加到某个网站的任意 pdf,这会使这个 FK 为空。 SQLAlchemy 允许可以为空的 FK,但是当它实际实现时,我得到了两个失败之一。代码如下:

class Parent(Base):
    __tablename__ = "parent"

    id = Column(UUID, primary_key=True, index=True, default=uuid.uuid4)
    url = Column(String(STR_LEN), nullable=False)
    text = Column(sqlalchemyText, nullable=False)

    pdf = relationship("Child", back_populates='parent')

class Child(Base):
    __tablename__ = "child"

    id = Column(UUID, primary_key=True, index=True, default=uuid.uuid4)
    parent_id = Column(UUID, ForeignKey("parent.id"), nullable=True)
    text = Column(sqlalchemyText(2**32-1), nullable=True)

    parent = relationship("Pages", back_populates='pdf')

现在,当我尝试使用来自网站的 pdf 填充表格时,一切正常。但是,当我尝试使用未链接到网站的 pdf 填充 Child 表时,会出现以下错误之一:

    当我尝试为parent_id 赋予值Nonenull()0 等时,它告诉我我不遵循UUID 约束。这很公平,但我让它可以为空,所以我不确定如何真正给它一个空的东西。

    当我尝试只给它一个虚拟 uuid,使其只是一个孤立的 uuid 时,我收到外键约束失败的错误。

最终,我的问题是:我如何做到这一点,以便外键约束在我不想要它时不在乎,或者实际上给它这个空值而不抱怨?

我正在使用 mysql 数据库,所以如果有特定方言的解决方案,那很好(但我希望它是不可知的)。

【问题讨论】:

【参考方案1】:

我找到了解决我自己问题的方法,虽然它不是我最喜欢的,但效果很好......

使用零 UUID 有助于解决此问题,因为它每次都相同。你可以用代码调用它:

import uuid
zero_id = uuid.UUID(int=0)

我编写了一个脚本,该脚本在必要的表中填充了一行包含虚拟信息的行,其中所需的 uuid 为零。这样我就可以简单地将所有上传的文档链接到表中的那个 ID。 FK 约束都解决了,变量类型也很好。只是现在我有一堆我希望我不必拥有的额外代码。

【讨论】:

以上是关于SQLAlchemy 外键允许为空的主要内容,如果未能解决你的问题,请参考以下文章

西游之路——python全栈——ORM之SQLAlchemy外键与relationship的关系

sqlalchemy 简单使用

初学flask_sqlalchemy

使用 sqlalchemy 实现“软删除”系统

flask 使用 SQLAlchemy 的两种方式

python SQLAlchemy