【发布时间】:2015-11-06 13:06:38
【问题描述】:
我有一个必须复制的表(我无法控制它)。目标架构可以与原始架构相同,因此所有索引和约束都必须在没有名称的情况下隐式定义。
我将 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 是源和目标元数据,绑定):
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 中?
【问题讨论】:
-
您正在尝试克隆数据?如果架构相同
-
是的,我必须复制整个表格。架构可能相同也可能不同;问题显然会在出现时出现,但是,即使在不同的架构中,名称冲突也可能发生。
-
您尝试过类似
constraint.name = prefix + constraint.name的方法吗?在这种情况下,您将拥有约束的名称,它们将不同于现有的约束。 -
对不起,我的意思是设置索引名称
-
谢谢@pavel_form,我没想到。这仍然是一种解决方法,但如果我找不到更好的方法,我会继续这样做。
标签: python oracle python-3.x sqlalchemy