2017-03-08 1 views
0

내 모델의 기본 정수 ID를 uuid로 바꿔야합니다. 문제는 그것이 다른 모델 (foreignkey)에서 사용되는 beeing이라는 것입니다. 데이터를 잃지 않고이 작업을 수행하는 방법에 대한 아이디어가 있습니까?정수 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 값으로 ㄱ하는 id_tmp 열 및에 b_id_tmp 열을 추가에 내가 시도했습니다

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

증류기 마이그레이션은 비슷합니다. 외래 키에 b 조인 b를 갱신하여 a.b_id_tmp을 해당 UUID로 채우십시오. 그런 다음 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

관련 문제