Opened 5 years ago

Closed 4 years ago

#13179 closed Bug (duplicate)

last_insert_id method cannot find sequence

Reported by: grangerp Owned by: nobody
Component: Database layer (models, ORM) Version: 1.1
Severity: Normal Keywords:
Cc: Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: yes
Easy pickings: UI/UX:

Description

On line 55 of file django/db/postgresql/operations.py
method

 def last_insert_id(self, cursor, table_name, pk_name):
        cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name))
        return cursor.fetchone()[0]

should be like

def last_insert_id(self, cursor, table_name, pk_name):
    cursor.execute("SELECT CURRVAL(pg_get_serial_sequence('%s', '%s'))" % (table_name, pk_name))
    return cursor.fetchone()[0]

because the sequence can have different name that {table_name}_{pk_name}_seq

Change History (6)

comment:1 Changed 5 years ago by grangerp

  • Component changed from Uncategorized to Database layer (models, ORM)
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 5 years ago by russellm

  • Has patch set
  • Needs tests set
  • Patch needs improvement set
  • Triage Stage changed from Unreviewed to Accepted

The line referenced isn't the only place the %s_%s_seq construction is used; there are a couple of other places in the same file.

comment:3 Changed 5 years ago by akaariai

  • Triage Stage changed from Accepted to Design decision needed

This works only if the pk field is in fact serial or bigserial, but not for columns of type
pk integer primary key default nextval('foobar_seq').

Tested on postgresql 8.4.3:

postgrs=# \d foobar
                        Table "public.foobar"
 Column |  Type   |                    Modifiers                     
--------+---------+--------------------------------------------------
 id     | integer | not null default nextval('foobar_seq'::regclass)
Indexes:
    "foobar_pkey" PRIMARY KEY, btree (id)

postgres=# select pg_get_serial_sequence('foobar', 'id');
 pg_get_serial_sequence 
------------------------
 
(1 row)

postgres=# \d foobar2
                         Table "public.foobar2"
 Column |  Type   |                      Modifiers                       
--------+---------+------------------------------------------------------
 id     | integer | not null default nextval('foobar2_id_seq'::regclass)

postgres=# select pg_get_serial_sequence('foobar2', 'id');
 pg_get_serial_sequence 
------------------------
 public.foobar2_id_seq
(1 row)

For any custom database schema using default nextval instead of serial this would be a backwards incompatible change.

It is probably better to use a meta option (as in #13295) to allow overriding the sequence name when the default doesn't work.

comment:4 Changed 4 years ago by lukeplant

  • Type set to Bug

comment:5 Changed 4 years ago by lukeplant

  • Severity set to Normal

comment:6 Changed 4 years ago by jacob

  • Resolution set to duplicate
  • Status changed from new to closed

Marking as a duplicate of #13295 -- that's the correct fix here.

Note: See TracTickets for help on using tickets.
Back to Top