gpt4 book ai didi

python - 如何使用 SQLAlchemy 复制 Oracle 中的唯一约束?

转载 作者:太空宇宙 更新时间:2023-11-03 17:30:06 25 4
gpt4 key购买 nike

我有一个必须复制的表(我无法控制该表)。目标架构可以与原始架构相同,因此所有索引和约束都必须隐式定义,无需名称。

我使用的是 Python 3.4.3、SQLAlchemy 1.0.8 和 cx_oracle 5.2。

表格是这样的:

CREATE TABLE "MY_TABLE" 
( "ITEMID" NUMBER(*,0) NOT NULL ENABLE,
"LABEL" NVARCHAR2(80) NOT NULL ENABLE,
"FIRSTCHILDID" NUMBER(*,0) NOT NULL ENABLE,
"LASTCHILDID" NUMBER(*,0) NOT NULL ENABLE,
"DEFAULTPARENTID" NUMBER(*,0) NOT NULL ENABLE,
"PICTUREID" NUMBER(6,0) NOT NULL ENABLE,
"SECURITYID" NUMBER(*,0) NOT NULL ENABLE,
PRIMARY KEY ("ITEMID")
UNIQUE ("LABEL"));

我使用的代码位于 https://gist.github.com/toyg/9fb541ff3dbc8c175329但它的核心是这样的(smeta和dmeta是源和目标元数据,绑定(bind)的):

table = Table(table_name, smeta, autoload=True)
target_name = prefix + str(table.name)
target_table = table.tometadata(dmeta, name=target_name)
for constraint in target_table.constraints:
constraint.name = None
target_table.metadata.create_all(dengine)

失败并出现以下错误:

sqlalchemy.exc.DatabaseError: (cx_Oracle.DatabaseError) 
ORA-00955: name is already used by an existing object
[SQL: b'CREATE UNIQUE INDEX sys_c009016 ON "TMP_MY_TABLE" (label)']

这是因为 SQLAlchemy 在创建表后尝试创建唯一索引,但已经太晚了:CREATE INDEX 需要一个名称,因此 SA 使用与现有名称相同的名称,并且失败。

我尝试在创建之前将索引名称设置为 None,以给 SA 一个提示,但这会导致错误,因为它始终需要一个字符串。

有没有办法告诉 SA 立即将该死的 UNIQUE 子句附加到表 DDL 中?

最佳答案

“UNIQUE INDEX”表示使用Index 构造。它的 DDL 不在 CREATE TABLE 内发出。听起来您正在寻找 UniqueConstraint 构造。在这种情况下,Oracle 可能会将您首次创建的 UniqueConstraint 对象的反射信息返回为具有 unique=True 的 Index 对象(这些构造是“不同的”) ,但在许多后端,它们是同义的和/或混合匹配的,有时甚至是镜像的,这完全令人困惑)。

最终,如果您希望将 UNIQUE 关键字作为内联约束,则需要使用 UniqueConstraint 对象,并且需要删除此 Index从表中 - 您也许可以使用table.indexes.remove(index)Index 对象不会位于 table.constraints 中。您可能希望以更具编程性的方式来“复制”表,而不是使用 tometadata()。也许考虑使用 inspection interface直接构建您想要的Table

关于python - 如何使用 SQLAlchemy 复制 Oracle 中的唯一约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31990351/

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