Which method to generate IDs for objects?
Hi! I am just experimenting with ZClasses and I ran into the following problem: when I instantiate an object this object needs an unique ID. There are some ways to generate this. First of all I thought of the system time as ID, but this can make problems, even though not with high probability. Does anybody out there have a better solution, I think of an ID generation like in a sequence: object_id_001, object_id_002, ... but how can I determine the last object ID? Other (better, more simple) ideas? Juergen
I am just experimenting with ZClasses and I ran into the following problem: when I instantiate an object this object needs an unique ID. There are some ways to generate this. First of all I thought of the system time as ID, but this can make problems, even though not with high probability. Does anybody out there have a better solution, I think of an ID generation like in a sequence: object_id_001, object_id_002, ... but how can I determine the last object ID?
Other (better, more simple) ideas?
I don't know if this is very efficient/elegant/etc*, but I use it to get a unique id within a folder... ------------- intid = 1 while 1: if hasattr(photo_folder, str(intid)): intid = intid + 1 else: photo_folder.manage_addProduct['ExtFile'].manage_addExtImage(id=str(intid), file=f_request[photo], create_prev=1, maxx=50, maxy=50, ratio=1) break ------------- photo_folder is a previously defined in the script object. hth tim * I guess it gets a bit less useful as you start having lots of objects in your folder... I have a max of 4.
On Wed, Jan 16, 2002 at 12:21:45PM -0000, Tim Hicks wrote:
I don't know if this is very efficient/elegant/etc*, but I use it to get a unique id within a folder...
------------- intid = 1 while 1: if hasattr(photo_folder, str(intid)): intid = intid + 1 else:
How thread-safe is this? I Java I would write a syncronise block around i=i+1, because of the following example: Timestep 1: i==5; two threads read it Timestep 2: both do i=5+1 --> There will be two Classes with id==6. I have seen a counter object somewhere. I think it is thread safe. Is there something like syncronise blocks in python/zope? -- Open Source Software Solutions Thomas Guettler <guettli@thomas-guettler.de> http://www.thomas-guettler.de
Thomas Guettler writes:
On Wed, Jan 16, 2002 at 12:21:45PM -0000, Tim Hicks wrote:
I don't know if this is very efficient/elegant/etc*, but I use it to get a unique id within a folder...
------------- intid = 1 while 1: if hasattr(photo_folder, str(intid)): intid = intid + 1 else:
How thread-safe is this? I Java I would write a syncronise block around i=i+1, because of the following example: It is not thread safe and therefore the later "_setObject" may raise a BadRequest exception due to duplicate ids.
It is therefore better, to use the "_setObject" directly: while 1: try: self._setObject(str(intid),o); break; except BadRequest: intid= intid+1 This, still, is not thread safe. But conflicting threads write the same object. The standard ZODB conflict resolution will normally abort one of the conflicting transactions and restart the corresponding request. I store the "intid" counter in an object attribute, in order not to make so many unsuccessful trials. True, usually, ZODB objects should not be used for counting. But I write the object anyway (for the new object), thus there is no additional penalty to write the counter. Dieter
Thomas Guettler writes:
On Wed, Jan 16, 2002 at 12:21:45PM -0000, Tim Hicks wrote:
I don't know if this is very efficient/elegant/etc*, but I use it to get a unique id within a folder...
------------- intid = 1 while 1: if hasattr(photo_folder, str(intid)): intid = intid + 1 else:
How thread-safe is this? I Java I would write a syncronise block around i=i+1, because of the following example: It is not thread safe and therefore the later "_setObject" may raise a BadRequest exception due to duplicate ids.
It is therefore better, to use the "_setObject" directly:
while 1: try: self._setObject(str(intid),o); break; except BadRequest: intid= intid+1
I follow this, and understand the points you both raise. Dieter, your (partial) solution won't work from a PythonScript though because of the _ in _setObject, right?
This, still, is not thread safe. But conflicting threads write the same object. The standard ZODB conflict resolution will normally abort one of the conflicting transactions and restart the corresponding request.
Noted for future reference.
I store the "intid" counter in an object attribute, in order not to make so many unsuccessful trials. True, usually, ZODB objects should not be used for counting. But I write the object anyway (for the new object), thus there is no additional penalty to write the counter.
I don't understand why storing the 'intid' in an object attribute cuts down on the unsuccessful trials. Do you mean storing it persistently in the parent object? tim
Tim Hicks writes:
It is not thread safe and therefore the later "_setObject" may raise a BadRequest exception due to duplicate ids.
It is therefore better, to use the "_setObject" directly:
while 1: try: self._setObject(str(intid),o); break; except BadRequest: intid= intid+1
I follow this, and understand the points you both raise. Dieter, your (partial) solution won't work from a PythonScript though because of the _ in _setObject, right? Right!
...
I store the "intid" counter in an object attribute, in order not to make so many unsuccessful trials. True, usually, ZODB objects should not be used for counting. But I write the object anyway (for the new object), thus there is no additional penalty to write the counter.
I don't understand why storing the 'intid' in an object attribute cuts down on the unsuccessful trials. Do you mean storing it persistently in the parent object? Precisely that.
Dieter
On Thu, Jan 17, 2002 at 11:30:46PM +0100, Dieter Maurer wrote:
Thomas Guettler writes:
On Wed, Jan 16, 2002 at 12:21:45PM -0000, Tim Hicks wrote:
I don't know if this is very efficient/elegant/etc*, but I use it to get a unique id within a folder...
------------- intid = 1 while 1: if hasattr(photo_folder, str(intid)): intid = intid + 1 else:
How thread-safe is this? I Java I would write a syncronise block around i=i+1, because of the following example: It is not thread safe and therefore the later "_setObject" may raise a BadRequest exception due to duplicate ids.
It is therefore better, to use the "_setObject" directly:
while 1: try: self._setObject(str(intid),o); break; except BadRequest: intid= intid+1
Sorry, I don't understand this. Ain't there a easier way to get something like a syncronized block in java? BTW, I found something in lib/python/ZODB/tests/ConflictResolution.py: The PCounter class. I think it is a persistent thread safe counter. thomas -- Thomas Guettler <guettli@thomas-guettler.de> http://www.thomas-guettler.de
Thomas Guettler writes:
It is therefore better, to use the "_setObject" directly:
while 1: try: self._setObject(str(intid),o); break; except BadRequest: intid= intid+1
Sorry, I don't understand this. Ain't there a easier way to get something like a syncronized block in java? The standard Zope execution is easier than explicit synchronization: you do not need to synchronize. Details in a paper about ZODB3 on Zope.org.
But in rare cases, you might get a "BadRequest" exception, unless you are carefull. Assigning ids can be one such case. You can use locking in Zope, too. See "SharedResource" on <http://www.dieter.handshake.de/pyprojects/zope>
BTW, I found something in lib/python/ZODB/tests/ConflictResolution.py: The PCounter class. I think it is a persistent thread safe counter. Thank you for this hint.
Dieter
hello juergen, a simple approach: i would use hash() on a unique "property" of your objects... this can be the source of the document or a combination of unique properties... for example: if you would like to store emails, you could use a hash of "sender","subject","date","body". id=str(hash(sender+subject+date+body)) mails with exactly the same values for that would be identical (result will be the same hash-value)... and there's no need to store them. this would fail if you have no unique properties... but that would mean to create thousands of documents with exactly the same contents & props... very unlikely i think, because one document would be enough in such a case. another way could be: id = "objId_%d" % len(container.objectValues()) this results in unique values if you don't delete an object out of the container... i think there may be better ways, but hope this helps a bit... mjablonski
Hi!
I am just experimenting with ZClasses and I ran into the following problem: when I instantiate an object this object needs an unique ID. There are some ways to generate this. First of all I thought of the system time as ID, but this can make problems, even though not with high probability. Does anybody out there have a better solution, I think of an ID generation like in a sequence: object_id_001, object_id_002, ... but how can I determine the last object ID?
Other (better, more simple) ideas?
Juergen
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
Hi, Maik Jablonski wrote:
a simple approach: i would use hash() on a unique "property" of your objects... this can be the source of the document or a combination of unique properties...
for example: if you would like to store emails, you could use a hash of "sender","subject","date","body".
id=str(hash(sender+subject+date+body))
mails with exactly the same values for that would be identical (result will be the same hash-value)... and there's no need to store them.
No, not really. A hash is just very likely to be different for different data, but it is not guaranteed. Markus -- "GPL software is not free - the cost is cooperation"
Hash! - Good idea! --On Mittwoch, 16. Jänner 2002 16:25 +0100 Markus Schaber <markus.schaber@student.uni-ulm.de> wrote:
mails with exactly the same values for that would be identical (result will be the same hash-value)... and there's no need to store them.
No, not really. A hash is just very likely to be different for different data, but it is not guaranteed.
That's right, but when you use a cryptographic one-way-hash like MD5 or SHA-1 it's not very likely. Besides that it would mean that there cannot be more than one object with exactly the same content. Juergen
Hi Maik! Thanks for your quick answer. --On Mittwoch, 16. Jänner 2002 15:13 +0100 Maik Jablonski <maik.jablonski@uni-bielefeld.de> wrote:
another way could be:
id = "objId_%d" % len(container.objectValues())
this results in unique values if you don't delete an object out of the container...
i think there may be better ways, but hope this helps a bit...
Thanks, it helped a lot. With the id of the last object inserted into the container I could create a sequence of ids. Is there a simple way to get this id? Juergen
hello juergen, i think this will give you really unique id's... part of a python script # get a unique id in context for an object id = len(context.objectIds()) # get the number of objects in context => maybe already a free id? while hasattr(context,str(id)): # to be sure: test if id exists already and search for a free id... id = id + 1 return(str(id)) # and that's what we need... hope this will get you through... mjablonski
Maik Jablonski wrote:
hello juergen,
i think this will give you really unique id's... part of a python script
# get a unique id in context for an object
id = len(context.objectIds()) # get the number of objects in context => maybe already a free id? while hasattr(context,str(id)): # to be sure: test if id exists already and search for a free id... id = id + 1 return(str(id)) # and that's what we need...
In reality it is not guaranteed to give a unique id. Another proces could come to the same id if you are unlucky. you should probably use the FScounter to be certain. regards Max M
participants (8)
-
Dieter Maurer -
Juergen R. Plasser / HEXAGON -
Maik Jablonski -
Markus Schaber -
Max M -
Thomas Guettler -
Tim Hicks -
Tim Hicks