使用DataMapper和旧版PostgreSQL数据库自动增量密钥

时间:2011-03-14 19:39:17

标签: ruby postgresql doctrine datamapper

我想要使用Ruby DataMapper访问现有的PostgreSQL数据库。我已根据现有数据库模式创建了模型,但主键不会自动递增。

我的模特看起来像这样:

class Company
  include DataMapper::Resource

  property :id, Serial
  property :name, String
end

id定义为Serial无效:当我创建实例时,由于违反了非空约束,我得到DataObjects::IntegrityError

数据库与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 :(得分:0)

您可以使用表达式中的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');