gpt4 book ai didi

python - 我如何告诉 SQLAlchemy 对 Session.merge 使用不同的身份规则(而不是 PK)?

转载 作者:太空宇宙 更新时间:2023-11-03 16:07:51 24 4
gpt4 key购买 nike

我有一个遗留数据库,它是盲目地使用自动增量 ID 创建的,即使表中有一个完全有效的自然键。

这最终会导致代码散落,代码如下:

Fetch row with natural key 'x'
if exists:
update row with NK 'x'
else:
insert row with NK 'x'

本质上是一个更新插入。

此用例(更新插入)包含在 Session.merge() 中来自 SQLAlchemy。但 SA 只会查看表的主键来协调是否必须执行插入或更新。然而,在现有的数据库中,PK 并不代表行的真实身份,这与它应该做的相反。所以同一个身份可以出现多个自增ID。还有一些其他业务规则可以确保唯一性。但今天的 ID 1 明天可能是 ID 3246!

目前没有好方法以合理的方式修改数据库,因为太多遗留应用程序依赖于现有的结构。

为了举一个具体的例子,假设我们在表中有网络设备,并将它们的主机名作为自然键。 当前数据库看起来像这样:

CREATE TABLE device (
id SERIAL PRIMARY KEY,
hostname TEXT UNIQUE,
some_other_column TEXT
)

对应的SA型号:

class Device(Base):
id = Column(Integer, primary_key=True)
hostname = Column(String(256))
some_other_column = Column(String(20))

我希望能够执行以下操作:

mydevice = Device(hostname='hello-world', some_other_column='foo')
merged_device = session.merge(mydevice)
session.commit()

在此示例中,我希望 SA 执行“插入或更新”。但对于当前模型,这实际上会导致错误(由于唯一的主机名约束)。

可以hostname列指定为SA模型中的主键(并将PK按原样保留在数据库中)。但这看起来有点老套。是否没有更明确且易于理解的方法来告诉 SQLAlchemy 它应该使用“主机名”作为身份?如果是,怎么办?

最佳答案

在这种情况下,我发现最好对 sqlalchemy 撒谎。告诉它自然键是主键。

class Device(Base):
hostname = Column(String(256), primary_key=True)
some_other_column = Column(String(20))

关于python - 我如何告诉 SQLAlchemy 对 Session.merge 使用不同的身份规则(而不是 PK)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39616663/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com