繁体   English   中英

如何使用SQLAlchemy在Oracle中复制唯一性约束?

[英]How do I copy Unique constraint in Oracle with SQLAlchemy?

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

我正在将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上?

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

在一天结束时,如果你想UNIQUE关键字,你需要使用内联约束UniqueConstraint对象,你需要删除该Index从上表-你也许可以逃脱table.indexes.remove(index) Index对象将不在table.constraints 您可能希望以一种更具编程性的方式而不是使用tometadata()对表进行“复制”。 看看直接使用检查界面 ,然后从中构建所需的Table

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM