2017-03-08 10 views
0

私のモデルのデフォルトの整数IDをuuidに置き換える必要があります。問題は、それが別のモデル(外部キー)で使用されているということです。 データを失うことなくこの操作を実行する方法については何ですか?整数IDフィールドをuuidに置き換えます

class A(Base): 
    __tablename__ = 'a' 

    b_id = Column(
     GUID(), ForeignKey('b.id'), nullable=False, 
     server_default=text("uuid_generate_v4()") 
    ) 

class B(Base): 
    __tablename__ = 'b' 
    id = Column(
     GUID(), primary_key=True, 
     server_default=text("uuid_generate_v4()") 
    ) 

残念ながら、それは動作しませんまた、私はその関係を壊す恐れがあります。

op.execute('ALTER TABLE a ALTER COLUMN b_id SET DATA TYPE UUID USING (uuid_generate_v4())') 

答えて

2

に自動生成されたUUID値をbにid_tmp列、およびb_id_tmp列を追加:私が試した

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) default for column "id" cannot be cast automatically to type uuid 

アレンビックの移行は次のように見えます。対応するUUIDでa.b_id_tmpを入力するように外部キーの結合bを更新します。次に、a.b_idb.idをドロップし、追加した列の名前を変更して、主キーと外部キーを再確立します。ただ、脇など

CREATE TABLE a(id int PRIMARY KEY, b_id int); 
CREATE TABLE b(id int PRIMARY KEY); 

ALTER TABLE a ADD CONSTRAINT a_b_id_fkey FOREIGN KEY(b_id) REFERENCES b(id); 

INSERT INTO b VALUES (1), (2), (3); 
INSERT INTO a VALUES (1, 1), (2, 2), (3, 2); 

ALTER TABLE b ADD COLUMN id_tmp UUID NOT NULL DEFAULT uuid_generate_v1mc(); 
ALTER TABLE a ADD COLUMN b_id_tmp UUID; 

UPDATE a SET b_id_tmp = b.id_tmp FROM b WHERE b.id = a.b_id; 

ALTER TABLE a DROP COLUMN b_id; 
ALTER TABLE a RENAME COLUMN b_id_tmp TO b_id; 
ALTER TABLE b DROP COLUMN id; 
ALTER TABLE b RENAME COLUMN id_tmp TO id; 
ALTER TABLE b ADD PRIMARY KEY (id); 
ALTER TABLE a ADD CONSTRAINT b_id_fkey FOREIGN KEY(b_id) REFERENCES b(id); 

彼らはあなたが行にいくつかを生成する場合はわかりますいくつかの再現性のある情報が含まれているので、それがV4よりもV1のUUIDインデックスへのより効率的です。これは、外部のセキュリティ上の理由により高いランダム性が必要な場合を除いて、わずかな節約です。

+0

私はこれが既存の関係をどのように保つのかを確信していません。 SQL構文やPython/alembicコードで表示できますか? – user2091046

+1

あなたがそれを見たならば、Raiders of the Lost Arkからのbag-of-sandトリックのSQLに相当するものですが、巨大な岩を除いては例外です。私は例を追加しました。 – dmfay

関連する問題