我最近开始使用PostgreSQL开发应用程序作为后端数据库(强加于我),之前没有Postgres的经验。到目前为止它并没有太糟糕,但现在我遇到了一个我无法找到答案的问题。
我创建了一个批处理脚本,它为服务器上的特定数据库运行pg_dump命令。该批处理文件由pgAgent按计划执行。
pg_dump本身似乎工作正常。所有数据库结构和数据都转储到文件中。但是序列都设置为1.例如,对于表 tbl_departments ,序列转储如下所示:
CREATE SEQUENCE "tbl_departments_iID_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE "tbl_departments_iID_seq" OWNER TO postgres;
ALTER SEQUENCE "tbl_departments_iID_seq" OWNED BY tbl_departments."iID";
在此特定示例中,序列应设置为以8开头,因为最后插入的记录的iID = 7。
如何让pg_dump设置每个表可用的下一个序列起始编号?
转储命令是: %PGBIN%pg_dump -h 192.168.0.112 -U postgres -F p -b -v --inserts -f“\\ 192.168.0.58 \ PostgresDB \ backup \ internals_db.sql”Internals
修改
我想我已经找到了这个问题,虽然我仍然不知道如何解决这个问题: 如果我打开pgAdmin并为tbl_departments生成CREATE脚本,它看起来像这样:
CREATE TABLE tbl_departments
(
"iID" serial NOT NULL, -- id, autoincrement
"c150Name" character varying(150) NOT NULL, -- human readable name for department
"bRetired" boolean NOT NULL DEFAULT false, -- if TRUE that it is no longer active
"iParentDept" integer NOT NULL DEFAULT 0, -- ID of the parent department
CONSTRAINT tbl_departments_pkey PRIMARY KEY ("iID")
)
pg_dump语句是:
CREATE TABLE tbl_departments (
"iID" integer NOT NULL,
"c150Name" character varying(150) NOT NULL,
"bRetired" boolean DEFAULT false NOT NULL,
"iParentDept" integer DEFAULT 0 NOT NULL
);
ALTER TABLE tbl_departments OWNER TO postgres;
COMMENT ON TABLE tbl_departments IS 'list of departments';
COMMENT ON COLUMN tbl_departments."iID" IS 'id, autoincrement';
COMMENT ON COLUMN tbl_departments."c150Name" IS 'human readable name for department';
COMMENT ON COLUMN tbl_departments."bRetired" IS 'if TRUE that it is no longer active';
COMMENT ON COLUMN tbl_departments."iParentDept" IS 'ID of the parent department';
CREATE SEQUENCE "tbl_departments_iID_seq"
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
ALTER TABLE "tbl_departments_iID_seq" OWNER TO postgres;
ALTER SEQUENCE "tbl_departments_iID_seq" OWNED BY tbl_departments."iID";
INSERT INTO tbl_departments VALUES (1, 'Information Technologies', false, 0);
INSERT INTO tbl_departments VALUES (2, 'Quality Control', false, 0);
INSERT INTO tbl_departments VALUES (3, 'Engineering', false, 0);
INSERT INTO tbl_departments VALUES (5, 'Quality Assurance', false, 0);
INSERT INTO tbl_departments VALUES (6, 'Production', false, 2);
ALTER TABLE ONLY tbl_departments
ADD CONSTRAINT tbl_departments_pkey PRIMARY KEY ("iID");
SELECT pg_catalog.setval('"tbl_departments_iID_seq"', 1, false);
pg_dump将iID列设置为整数而不是串行,这会禁用自动递增。 setval也设置为1而不是7。正如人们所期望的那样。
当我打开前端应用程序并去添加新部门时,它失败了,因为我提供的是:新部门的名称,活动/禁用(真/假),父部门的ID。 (如果没有父母,则为0)。
我期望DB自动创建新记录主键iID,据我所知,这是任何RDBMS的预期基本功能。
因为pg_dump将序列转换为整数,所以自动递增停止。
答案 0 :(得分:2)
没有理由担心。
生成的SQL文件将恢复序列的当前值。
使用编辑器打开文件,然后查找setval
。
应该有这样的行:
SELECT pg_catalog.setval('test_id_seq', 1234, true);
如果找不到它,则意味着INSERT命令设置序列的正确值。
正如Craig注意到的那样,在转储原始数据库时,序列的当前值必须等于1。您可能已直接插入iID
值,而不是使用default
。在这种情况下,不使用序列。
因此我建议从头开始,但是在两个数据库中:
答案 1 :(得分:2)
pg_dump将iID列设置为整数而不是串行,这会禁用自动增量。
这是正常的。请参阅the manual。
SERIAL
基本上只是CREATE SEQUENCE
的简写,然后是integer
列,使该序列成为default
的{{1}}。
setval也设置为1而不是7。正如人们所期望的那样。
我只能通过假设DB中的序列起始点为1来解释这一点。也许是由于先前尝试运行DDL来改变它,例如nextval('seq_name')
或setval
?
alter sequence
它是你期望的起点。然后,只要您不运行其他setval
命令,setval
命令等,您就可以了。
也许应用程序可以直接插入值,而不使用序列?