pg_dump序列设置

时间:2015-10-09 08:38:10

标签: postgresql sequences pg-dump

我最近开始使用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将序列转换为整数,所以自动递增停止。

2 个答案:

答案 0 :(得分:2)

没有理由担心。 生成的SQL文件将恢复序列的当前值。 使用编辑器打开文件,然后查找setval。 应该有这样的行:

SELECT pg_catalog.setval('test_id_seq', 1234, true);

如果找不到它,则意味着INSERT命令设置序列的正确值。

正如Craig注意到的那样,在转储原始数据库时,序列的当前值必须等于1。您可能已直接插入iID值,而不是使用default。在这种情况下,不使用序列。

因此我建议从头开始,但是在两个数据库中:

  • 像问题一样进行SQL转储,
  • 创建一个新数据库,
  • 在新数据库中运行sql脚本,
  • 检查相应的串行列是否在两个数据库中具有相同的声明
  • 比较两个数据库中相应序列的当前值。

答案 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命令等,您就可以了。

也许应用程序可以直接插入值,而不使用序列?