#9302: postgresql: currval of sequence is not yet defined in this session: fix
---------------------------------------------------+------------------------
Reporter:
bu...@erentil.net | Owner: nobody
Status: closed | Milestone:
Component: Database layer (models, ORM) | Version: 1.0
Resolution: invalid | Keywords:
Stage: Unreviewed | Has_patch: 1
Needs_docs: 0 | Needs_tests: 0
Needs_better_patch: 0 |
---------------------------------------------------+------------------------
Changes (by marcdm):
* status: new => closed
* resolution: => invalid
Comment:
This patch is actually invalid. The error happens when you try to select
the value for the auto-incrementing id of the last item inserted. The
probem usually arises when you try schema evolution by dropping ''some''
tables, and you don't always use DROP TABLE .... CASCADE;.
When creating a table, Django does something like (taken from ./manage.py
sql auth):
{{{
CREATE TABLE "auth_message" (
"id" serial NOT NULL PRIMARY KEY,
"user_id" integer NOT NULL REFERENCES "auth_user" ("id") DEFERRABLE
INITIALLY DEFERRED,
"message" text NOT NULL
)
;
}}}
By declaring that the "id" column is serial, PostgreSQL will implicitly
create a ''sequence object'' named :
'''{{{ auth_message_id_seq }}}'''
However, if you go into the database terminal, and issue a command to
{{{ DROP TABLE auth_message; }}}
without using CASCADE, and without isssuing a DROP SEQUENCE command, then,
when you recreate the table with the sql from before, Postgres will now
create a sequence object named
'''{{{ auth_message_id_seq1 }}}'''
And this is the root of the problem that this "bug" and patch addresses.
The problem with this patch is that, it allows you to continue to get the
''last_value'' from the wrong sequence object. This means that, for one,
foreign key fields in the django admin site, return wrong values when you
try to create a foreign key object using the popup.
The real solution is, if you get this error from PostgreSQL, verify the
sequence being used for a field by looking at the table structure using
{{{
\d [tablename]
}}}
For example (simulated to illustrate a point. don't try to delete the
auth_message table to re-enact this) :
{{{
\d auth_message
returns :
--------------
Table "public.auth_message"
Column | Type | Modifiers
---------+---------+-----------------------------------------------------------
id | integer | not null default
nextval('auth_message_id_seq1'::regclass)
user_id | integer | not null
message | text | not null
Indexes:
"auth_message_pkey" PRIMARY KEY, btree (id)
"auth_message_user_id" btree (user_id)
Foreign-key constraints:
"user_id_refs_id_650f49a6" FOREIGN KEY (user_id) REFERENCES
auth_user(id) DEFERRABLE INITIALLY DEFERRED
}}}
The ''id'' column gets its id from auth_message_id_seq1 But django will be
trying to read the last id from auth_message_id_seq which now stands
stagnant because no table uses it, and will not get ''nextval'' called on
it when you add a row.
You can use the following commands to your discretion in solving it :
{{{
DROP SEQUENCE auth_message_id_seq;
ALTER SEQUENCE auth_message_id_seq1 RENAME TO auth_message_id_seq;
ALTER TABLE auth_message ALTER "id" SET DEFAULT
nextval('auth_message_id_seq'::regclass);
}}}
And problem solved.
--
Ticket URL: <
http://code.djangoproject.com/ticket/9302#comment:2>