Opened 7 years ago

Closed 6 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 7 years ago by grangerp

Component: UncategorizedDatabase layer (models, ORM)

comment:2 Changed 7 years ago by Russell Keith-Magee

Has patch: set
Needs tests: set
Patch needs improvement: set
Triage Stage: UnreviewedAccepted

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 7 years ago by Anssi Kääriäinen

Triage Stage: AcceptedDesign 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 6 years ago by Luke Plant

Type: Bug

comment:5 Changed 6 years ago by Luke Plant

Severity: Normal

comment:6 Changed 6 years ago by Jacob

Resolution: duplicate
Status: newclosed

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

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