Создание последовательности PostgreSQL для поля (которое не является идентификатором записи)


Я работаю над приложением Ruby on Rails. Мы используем базу данных PostgreSQL.

Существует таблица с именем scores со следующими столбцами:

Column        | Type
--------------+-----------------------
id            | integer
value         | double precision
ran_at        | timestamp
active        | boolean
build_id      | bigint
metric_id     | integer
platform_id   | integer
mode_id       | integer
machine_id    | integer
higher_better | boolean
job_id        | integer
variation_id  | integer
step          | character varying(255)

Мне нужно добавить последовательность к job_id (примечание: для job нет модели).

Как мне создать эту последовательность?

2 8

2 ответа:

Использование CREATE SEQUENCE:

CREATE SEQUENCE scores_job_id_seq;  -- = default name for plain a serial

Затем добавьте столбец по умолчанию в scores.job_id:

ALTER TABLE scores ALTER COLUMN job_id SET DEFAULT nextval('scores_job_id_seq');

Если вы хотите привязать последовательность к столбцу (чтобы она удалялась при удалении столбца), также выполните:

ALTER SEQUENCE scores_job_id_seq OWNED BY scores.job_id;

Все это можно заменить с помощью псевдо-типа данныхserial для колонки job_id Начнем с:

Если в вашей таблице уже есть строки, вы можете установить SEQUENCE на следующее Самое высокое значение и заполнить недостающие серийные значения в таблице:

SELECT setval('scores_job_id_seq', COALESCE(max(job_id), 0)) FROM scores;

Необязательно:

UPDATE scores
SET    job_id = nextval('scores_job_id_seq')
WHERE  job_id IS NULL;

В единственное оставшееся различие, столбец serial также имеет значение NOT NULL. Вы можете хотеть или не хотеть этого тоже:

ALTER TABLE scores ALTER COLUMN job_id SET NOT NULL;

Но Вы не можете просто изменить тип существующего integer:

ALTER TABLE scores ALTER job_id TYPE serial;

serial не является фактическим типом данных. Это просто нотационная функция удобства для CREATE TABLE.

Итак, я выяснил, как это сделать, используя миграции ActiveRecord на Ruby on Rails. Я в основном использовал команды Erwin и справку из этой страницы и поместил их в файлы миграции. Вот эти шаги:

1. В терминале введите:

rails g migration CreateJobIdSequence
rails g migration AddJobIdSequenceToScores

2. Отредактируйте файлы миграции следующим образом:

20140709181616_create_job_id_sequence.rb :

class CreateJobIdSequence < ActiveRecord::Migration
  def up
    execute <<-SQL
      CREATE SEQUENCE job_id_seq;
    SQL
  end

  def down
    execute <<-SQL
      DROP SEQUENCE job_id_seq;
    SQL
  end
end

20140709182313_add_job_id_sequence_to_scores.rb :

class AddJobIdSequenceToScores < ActiveRecord::Migration
  def up
    execute <<-SQL
      ALTER SEQUENCE job_id_seq OWNED BY scores.job_id;
      ALTER TABLE scores ALTER COLUMN job_id SET DEFAULT nextval('job_id_seq');
    SQL
  end

  def down
    execute <<-SQL
      ALTER SEQUENCE job_id_seq OWNED BY NONE;
      ALTER TABLE scores ALTER COLUMN job_id SET NOT NULL;
    SQL
  end
end

3. Перенесите базу данных. В терминальном типе:

rake db:migrate