ฉันมีตาราง (ซึ่งฉันไม่สามารถควบคุมได้) ที่ฉันต้องคัดลอก สคีมาเป้าหมายสามารถเหมือนกับสคีมาดั้งเดิมได้ ดังนั้นดัชนีและข้อจำกัดทั้งหมดจึงต้องถูกกำหนดโดยไม่มีชื่อโดยปริยาย
ฉันใช้ 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 พยายามสร้างดัชนี Unique หลังจากสร้างตาราง เมื่อมันสายเกินไปแล้ว: CREATE INDEX จำเป็นต้องมีชื่อ ดังนั้น SA จะใช้ชื่อเดียวกันกับชื่อที่มีอยู่ แต่ล้มเหลว
ฉันพยายามตั้งชื่อดัชนีเป็นไม่มีก่อนที่จะสร้าง เพื่อให้คำแนะนำแก่ SA แต่นั่นส่งผลให้เกิดข้อผิดพลาดเนื่องจากคาดว่าจะมีสตริงอยู่ที่นั่นตลอดเวลา
มีวิธีใดบ้างที่จะบอก SA ให้ต่อท้าย UNIQUE clause เปื้อนเลือดเข้ากับตาราง DDL ทันที
constraint.name = prefix + constraint.name
บ้างไหม? ในกรณีนี้ คุณจะมีชื่อของข้อจำกัด และจะแตกต่างจากข้อจำกัดที่มีอยู่ - person pavel_form   schedule 13.08.2015