pg_dump setting of sequences

10,013

Solution 1

There is no reason for concern. The generated SQL file will restore current values of sequences. Open the file with an editor and look for setval. There should be lines like this:

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

If you cannot find them it means that INSERT commands set the proper value of a sequence.


As Craig noticed, the current value of the sequence had to be equal to 1 at the time of dump of the original database. You have probably inserted iID values directly, not using default. In that case the sequence is not used.

Therefore I suggest start from the beginning, but in two databases:

  • make an sql dump like in the question,
  • create a new database,
  • run the sql script in the new database,
  • check whether corresponding serial columns have the same declaration in both databases,
  • compare current values of corresponding sequences in both databases.

Solution 2

the pg_dump sets the iID column to integer rather than serial, which disabled the auto-incrementation.

That's normal. See the manual.

SERIAL is basically just shorthand for CREATE SEQUENCE and then an integer column that makes that sequence its default for nextval('seq_name').

The setval is also set to 1 rather than 7 as one would expect.

I can only explain that one by assuming that the sequence start point is 1 in the DB. Perhaps due to a prior attempt at running DDL that altered it, such as a setval or alter sequence?

setval it to the start point you expect. Then, so long as you don't run other setval commands, alter sequence commands, etc, you'll be fine.

Or maybe the app inserted values directly, without using the sequence?

Share:
10,013
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I've recently started developing apps with PostgreSQL as backend DB (imposed on me) with no previous experience of Postgres. So far it hasn't been too bad, but now I run into a problem to which I cannot find answer for.

    I created a batch scripts that runs a pg_dump command for a particular database on the server. This batch file is executed on schedule by the pgAgent.

    The pg_dump itself seems to work ok. All the database structure and data are dumped to a file. However the sequences are all set to 1. For example for table tbl_departments the sequence dump looks like this:

    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";
    

    In this particular example the sequence should be set to start with 8, since the last inserted record has iID = 7.

    How do I make the pg_dump set the sequence starting number the next one available for each table?

    The command for dump is: %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

    EDIT:

    I think I have found the issue, although I still don't know how to resolve this: If I open pgAdmin and generate CREATE script for tbl_departments, it look like this:

    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")
    )
    

    The pg_dump statement is:

        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);
    

    the pg_dump sets the iID column to integer rather than serial, which disabled the auto-incrementation. The setval is also set to 1 rather than 7 as one would expect.

    When I open the front-end application and go to add new department it fails because all I am providing is: name of new department, active/disabled (true/false), ID of parent dept. (0 if no parent).

    I am expecting for the new record primary key iID to be created automatically by the DB, which as far as I know is an expected basic feature of any RDBMS.

    because the pg_dump converts the serials to integers the auto-incrementation stops.

    • a_horse_with_no_name
      a_horse_with_no_name over 8 years
      What is the exact command you use to dump the structure? The file should contain the inserts for the table that is using that sequence, and those inserts should increment the sequence. Btw: you should avoid the use of quoted identifiers they are much more trouble than they are worth it (I also question the use of a tbl prefix - do you prefix all your classes in your programming language with Class as well?)
    • Admin
      Admin over 8 years
      I added the pg_dump command at the bottom of original comment
    • Admin
      Admin over 8 years
      The dump file script is building the table first, that sets the sequence to 0, and then does the inserts - but it actually inserts the values for iID. Would that hold the incrementation of sequence?
  • klin
    klin over 8 years
    In edit1 there were no setvals and in edit2 one suddenly appeared? Your question is inconsistent. I would suggest you to reset the test and start from the beginning.
  • Admin
    Admin over 8 years
    it "suddenly" appear as I was adding information in response to suggestions. I have edited the original to include all parts of dump file that have to do with creation, alteration and data insert for that particular table in order in which they appear.
  • Jeremy Caney
    Jeremy Caney over 2 years
    Can you offer an explanation? Why is this preferred over e.g. the top-rated answer?