[Zope] q: How should I get a guaranteed unique id in Zope?
Chris Kratz
chris.kratz@vistashare.com
Tue, 15 Jan 2002 12:39:44 -0500
On Tuesday 15 January 2002 02:33 am, you wrote:
> I'm probably missing something in postgresql where I can do an insert
> and have it return whatever jobid it automatically generates. On the
> Zope side, I'm using ZPsycoPg as my postgres connection.
>
> jpb
Hello Joe,
I don't know if you have found it yet, but in postgres if you create a table
with the primary key of type serial, you are guarranteed a unique id. This
creates a sequence behind the scenes which the table pulls the next id from.
You can then retrieve the inserted value by querying the sequence for the
current value. Since everything within a single request in zope is within a
transaction (given that you don't try to roll your own transaction code which
is a very bad thing unless you know what your doing...), you will always get
back the id of the record you just inserted. For simplicity, I usually put
them in separate ZSQL statements (one does the insert and the second pulls
the key for the inserted record), but you could include them within the same
ZSQL statement if you would like. It makes no difference in their execution
if they are separate or together.
For example, if you create a table like this...
create table simpletable ( idnum serial primary key, comment text);
psql will return...
NOTICE: CREATE TABLE will create implicit sequence 'simpletable_idnum_seq'
for SERIAL column 'simpletable.idnum'
NOTICE: CREATE TABLE/PRIMARY KEY will create implicit index
'simpletable_pkey' for table 'simpletable'
CREATE
or if you already created your table with a serial type, you can inspect the
sequence name with
\d simpletable
Table "simpletable"
Attribute | Type | Modifier
-----------+---------+-----------------------------------------------------------
idnum | integer | not null default
nextval('"simpletable_idnum_seq"'::text)
comment | text |
Index: simpletable_pkey
Notice it uses the nextval function as a trigger to get the next available
key value. The sequence name again is in the double quotes. If you want to
create and add a sequence, you can do that, but it is a little more
complicated. See the postgres doc for instructions.
Now, since we know the sequence name 'simpletable_idnum_seq', we can place
the following two statements into zope ZSQL objects:
insert into simpletable(comment) values('Some comment here');
select currval('simpletable_idnum_seq');
The second select calls a function which will always return the value of the
last record you inserted. The magic is that this will work across multiple
threads (Zope and postgres keep things straight) regardless of the number of
transactions, zope threads, or postgres threads that are currently running.
Hope that helps,
-Chris
--
Chris Kratz
Systems Analyst/Programmer
VistaShare LLC
www.vistashare.com