且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

修改Django AutoField起始值

更新时间:2022-10-23 21:54:42

在PostgreSQL中设置/重置序列的方法



(不一定要 max(id))。




  • 有这个问题的简单方法。您可以使用 setval()

      SELECT setval('tbl_id_seq'); 


  • 然后,标准的SQL方式是ALTER SEQUENCE

      ALTER SEQUENCE myseq RESTART WITH 1; 


  • 如果您想以除默认值1之外的数字重新启动序列:

      CREATE TABLE foo(id serial,a text); - 创建序列foo_id_seq
    INSERT INTO foo(a)VALUES('a'); - seq。以 - > 1

    ALTER SEQUENCE foo_id_seq START WITH 10; - 不重新启动序列
    INSERT INTO foo(a)VALUES('b'); - > 2

    ALTER SEQUENCE foo_id_seq RESTART; - 重新启动序列
    INSERT INTO foo(a)VALUES('c'); - >另外还有另一种方法,当你用 TRUNCATE
      TRUNCATE foo RESTART IDENTITY; 

    隐式执行 ALTER SEQUENCE foo_id_seq RESTART; / p>



I have and existing database, which I have migrated with SQLAlchemy to a new PostgreSQL database.

I moved all primary keys with the same values as before. Now I have tables filled with data, but the associated sequences starts from 1. I have pk values stored 1 to 2000.

Now, when I try to save something with Django, I have the

duplicate key value violates unique constraint regarding to the Primary Key.

How can I modify the sequence start values or escape this situation?
My current solution is:

conn = psycopg2.connect(...)
    for table_name in table_names:

        cursor = conn.cursor()
        cursor.execute("""
        SELECT setval('%s_id_seq', (SELECT COALESCE(MAX(id),0)+1 FROM %s));
        """% (table_name, table_name))

It works for me, but I don't like it.

Ways to set / reset a sequence in PostgreSQL

(not necessarily to max(id)).

  • There's the simple way you have in the question. You can set the sequence to start at an arbitrary number with setval():

    SELECT setval('tbl_id_seq');
    

  • Then there's the standard SQL way with ALTER SEQUENCE doing the same:

    ALTER SEQUENCE myseq RESTART WITH 1;
    

  • If you like to restart your sequences at numbers other than the default 1:

    CREATE TABLE foo(id serial, a text);      -- creates sequence "foo_id_seq"
    INSERT INTO foo(a) VALUES('a');           -- seq. starts with --> 1
    
    ALTER SEQUENCE foo_id_seq START WITH 10;  -- doesn't restart sequence
    INSERT INTO foo(a) VALUES('b');           --> 2
    
    ALTER SEQUENCE foo_id_seq RESTART;        -- restarts sequence
    INSERT INTO foo(a) VALUES('c');           --> 10
    

  • And there is another way, when you empty a table with TRUNCATE:

    TRUNCATE foo RESTART IDENTITY;
    

    Implicitly executes ALTER SEQUENCE foo_id_seq RESTART;