使用 DataMapper 和旧版 PostgreSQL 数据库自动增量键
我有一个现有的 PostgreSQL 数据库,我想使用 Ruby DataMapper 访问它。我已经根据现有的数据库模式创建了模型,但主键不会自动递增。
我的模型如下所示:
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 重新创建该行为?或者在这种情况下还有哪些其他(更好)的解决方案可以创建自动递增键?
I have an existing PostgreSQL database that I want to access with Ruby DataMapper. I have created my models according to the existing database schemata, but primary keys are not auto incremented.
My models look like this:
class Company
include DataMapper::Resource
property :id, Serial
property :name, String
end
Defining the id
as Serial
has no effect: when I create an instance I get an DataObjects::IntegrityError
because of a violated not-null constraint.
The database is shared with a PHP/Doctrine application, so I cannot change the schema. The PHP application uses a sequence to create the primary keys like this:
SELECT NEXTVAL('"production"."sequence_id_seq"')
INSERT INTO "production"."companies" ("name", "id") VALUES ('Acme Inc.', 40711)
The table looks like this:
CREATE TABLE production.companies
(
id bigint NOT NULL,
"name" character varying(255) NOT NULL,
CONSTRAINT companies_pkey PRIMARY KEY (id),
)
WITH (
OIDS=FALSE
);
This is the equivalent Doctrine schema definition:
CompanyOrm:
tableName: companies
columns:
id:
type: integer(8)
unsigned: 1
primary: true
sequence: sequence_id
name:
type: string(255)
notnull: true
How can I recreate that behavior with DataMapper? Or what other (better) solutions exist to create auto incrementing keys in this situation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以在表达式中使用
nextval()
函数来获取下一个序列值并将其用作id
:我对 DataMapper 的了解不够,无法判断是否可以可能会导致在 INSERT 中使用函数,但也许可以通过定义自己的 Datamapper 来实现此目的: :Property(而不是串行)?
或者,您可以更改表以使行默认使用序列,这不会破坏与手动使用相同序列的任何内容的兼容性:
You can use the
nextval()
function in an expression to fetch and use the next sequence value as theid
:I don't know enough about DataMapper to say whether or not it's possible to cause a function to be used in an INSERT, but maybe there's some way to do it by defining your own Datamapper::Property (instead of Serial)?
Alternatively, you could alter the table to make the row default to using the sequence, which shouldn't break compatibility with anything that manually uses the same sequence: