我想要使用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重新创建该行为?或者在这种情况下还有哪些其他(更好的)解决方案可以创建自动递增键?
答案 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');