9

Postgresql の主キーとして UUID を使用するように変換したいデータベースがあります。

深いマルチレベルの関連付けを持つ約 30 のテーブルがあります。現在のすべての ID を UUID に変換する「簡単な」方法はありますか?

これから: https://coderwall.com/p/n_0awq、移行中にテーブルを変更できることがわかります。私は次のようなことを考えていました:

for client in Client.all
  # Retrieve children
  underwritings = client.underwritings
  # Change primary key
  execute 'ALTER TABLE clients ALTER COLUMN id TYPE uuid;'
  execute 'ALTER TABLE clients ALTER COLUMN id SET DEFAULT uuid_generate_v1();'
  # Get new id - is this already generated?
  client_id = client.id
  for underwriting in underwritings
    locations = underwriting.locations
    other_record = underwriting.other_records...

    execute 'ALTER TABLE underwritings ALTER COLUMN id TYPE uuid;'
    execute 'ALTER TABLE underwritings ALTER COLUMN id SET DEFAULT uuid_generate_v1();'
    underwriting.client_id = client_id
    underwriting.saved
    underwriting_id = underwriting.id

    for location in locations
      buildings = location.buildings
      execute 'ALTER TABLE locations ALTER COLUMN id TYPE uuid;'
      execute 'ALTER TABLE locations ALTER COLUMN id SET DEFAULT uuid_generate_v1();'
      location.undewriting_id = underwriting_id
      location.save
      location_id = location.id

      for building in buildings
      ...
      end
    end
    for other_record in other_records
      ...
    end
    ... 
    ...
  end
end

質問:

  • これは機能しますか?
  • これを行う簡単な方法はありますか?
  • 主キーが変更される前に子レコードが取得された場合、子レコードは適切に取得されますか?
  • 変更テーブルが呼び出されるとすぐに、新しい主キーはすでに生成されていますか?

これを行う上での助けやヒントをありがとう。

4

3 に答える 3

1

外部キーを追加したくなくて、Rails マイグレーションを使用したかった。とにかく、他の人がこれをやろうとしている場合に私がしたことは次のとおりです(2つのテーブルの例、合計32を行いました):

  def change
    execute 'CREATE EXTENSION "uuid-ossp";'
    execute <<-SQL
      ALTER TABLE buildings ADD COLUMN guid uuid DEFAULT uuid_generate_v1() NOT NULL;
      ALTER TABLE buildings ALTER COLUMN guid SET DEFAULT uuid_generate_v1();
      ALTER TABLE buildings ADD COLUMN location_guid uuid;

      ALTER TABLE clients ADD COLUMN guid uuid DEFAULT uuid_generate_v1() NOT NULL;
      ALTER TABLE clients ALTER COLUMN guid SET DEFAULT uuid_generate_v1();
      ALTER TABLE clients ADD COLUMN agency_guid uuid;
      ALTER TABLE clients ADD COLUMN account_executive_guid uuid;
      ALTER TABLE clients ADD COLUMN account_representative_guid uuid;
    SQL

    for record in Building.all
      location = record.location
      record.location_guid = location.guid

      record.save
    end

    for record in Client.all
      agency = record.agency
      record.agency_guid = agency.guid

      account_executive = record.account_executive
      record.account_executive_guid = account_executive.guid unless account_executive.blank?

      account_representative = record.account_representative
      record.account_representative_guid = account_representative.guid unless account_representative.blank?

      record.save
    end

    execute <<-SQL
      ALTER TABLE buildings DROP CONSTRAINT buildings_pkey;
      ALTER TABLE buildings DROP COLUMN id;
      ALTER TABLE buildings RENAME COLUMN guid TO id;
      ALTER TABLE buildings ADD PRIMARY KEY (id);
      ALTER TABLE buildings DROP COLUMN location_id;
      ALTER TABLE buildings RENAME COLUMN location_guid TO location_id;

      ALTER TABLE clients DROP CONSTRAINT clients_pkey;
      ALTER TABLE clients DROP COLUMN id;
      ALTER TABLE clients RENAME COLUMN guid TO id;
      ALTER TABLE clients ADD PRIMARY KEY (id);
      ALTER TABLE clients DROP COLUMN agency_id;
      ALTER TABLE clients RENAME COLUMN agency_guid TO agency_id;
      ALTER TABLE clients DROP COLUMN account_executive_id;
      ALTER TABLE clients RENAME COLUMN account_executive_guid TO account_executive_id;
      ALTER TABLE clients DROP COLUMN account_representative_id;
      ALTER TABLE clients RENAME COLUMN account_representative_guid TO account_representative_id;
    SQL
  end
于 2013-07-21T21:32:09.717 に答える