Автоинкрементные ключи с использованием DataMapper с устаревшей базой данных PostgreSQL - PullRequest
0 голосов
/ 14 марта 2011

У меня есть база данных PostgreSQL, к которой я хочу получить доступ с помощью Ruby DataMapper.Я создал свои модели в соответствии с существующими схемами базы данных, но первичные ключи не увеличиваются автоматически.

Мои модели выглядят так:

class Company
  include DataMapper::Resource

  property :id, Serial
  property :name, String
end

Определение id как Serial не имеет никакого эффекта: когда я создаю экземпляр, я получаю DataObjects::IntegrityError из-за нарушения-null ограничение.

База данных используется совместно с приложением PHP / Doctrine, поэтому я не могу изменить схему.Приложение PHP использует последовательность для создания первичных ключей следующим образом:

SELECT NEXTVAL('"production"."sequence_id_seq"') 
INSERT INTO "production"."companies" ("name", "id") VALUES ('Acme Inc.', 40711)

Таблица выглядит следующим образом:

CREATE TABLE production.companies
(
  id bigint NOT NULL,
  "name" character varying(255) NOT NULL,
  CONSTRAINT companies_pkey PRIMARY KEY (id),
)
WITH (
  OIDS=FALSE
);

Это эквивалентное определение схемы Doctrine:

CompanyOrm:
  tableName: companies
  columns:
    id:
      type: integer(8)
      unsigned: 1
      primary: true
      sequence: sequence_id
    name:
      type: string(255)
      notnull: true

Как я могу воссоздать такое поведение с помощью DataMapper?Или какие другие (лучшие) решения существуют для создания автоинкрементных ключей в этой ситуации?

1 Ответ

0 голосов
/ 23 апреля 2011

Вы можете использовать функцию nextval() в выражении для извлечения и использовать следующее значение последовательности в качестве id:

INSERT INTO "production"."companies" ("name", "id") 
VALUES ('Acme Inc.', nextval('production.sequence_id_seq') )

Я не знаю достаточно о DataMapper, чтобы сказать, действительно лиМожно заставить функцию использоваться в INSERT, но, возможно, есть какой-то способ сделать это, определив свой собственный Datamapper :: Property (вместо Serial)?

В качестве альтернативы, выможет изменить таблицу так, чтобы строка по умолчанию использовала последовательность, что не должно нарушать совместимость с чем-либо, что вручную использует ту же последовательность:

ALTER TABLE production.companies 
  ALTER COLUMN id SET DEFAULT nextval('production.sequence_id_seq');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...