Thanks guys for your help I'm going to give Hermanns methods a go.

Morgan

Hermann Himmelbauer wrote:
> Am Montag, 21. Januar 2008 01:16 schrieb Morgan:
>   
>> Hi Guys,
>>
>> I have field that I want to put a unique identifier in. This unique Id i
>> would like to be a composite key or simply a random number. What do you
>> guys suggest for this, is there a particular method which works well for
>> some of you?
>>     
>
> That's a good question, I asked myself some weeks ago, here's how I solved 
> this: 
>
> In my case, I have database records that have sequential numbers as primary 
> keys. These keys can be calculated by the database and are unique by design 
> (as the primary index is unique).
>
> This record should hold another field, which should be also unique and in a 
> form of a 8-digit number. However, I'd rather not want this number to be 
> sequential, it should look random. The first way would have been to simple 
> generate a number via "random.randint(99999999)", look into the database, if 
> it's already in and if not, insert it. However, to guarantee that the number 
> is unique, one should create a unique index on this column. In case the 
> number is already there, the database will raise an error, which has to be 
> catched by the application. Another way would be to lock the table after the 
> select, so that the rare case, that another application instance inserts the 
> same number after my select, is avoided. So, the algorithm could look like 
> this (in pseudo code):
>
> # Variant 1 with exception handling
> while 1:
>   num = random.randint(99999999)
>   try:
>     insert into db_table (col1, col2, col_num, col3, ) % num
>   except UniqueNum_IndexViolated:
>     continue
>   else:
>     break
>
> # Variant 2 with locking
> while 1:
>   num = random.randint(99999999)
>   lock db_table
>   result = select * from db_table where col_num = num
>   if result: 
>     continue
>   else:
>     insert into db_table (col1, col2, col_num, col3, ....) % num
>     unlock db_table
>   continue
>
> My problem with variant (1) was that I could not find out how to lock a whole 
> table with SQLAlchemy, moreover, each insert needs a table lock and a select, 
> which is bad performance-wise. The problem with (2) was that I did not know 
> how to catch this specific exception, as I can't simply except any database 
> error but this specific index violation (which may be different on different 
> databases).
>
> My third idea, which I use now, is to calculate my "random" number out of my 
> sequential, unique primary index, which is generated by the database during 
> the insert. One helpful guy from #sqlalchemy helped me out with 
> the "randomization" of the sequential number with this algorithm:
>
> def mk_arb_seq(id):
>     """ Return an arbitrary number. This number is calculated out of
>     the given id. For that, it is multiplied by the large prime number"A".
>     Then a modulo operation with prime "M" where M < A. If "A" is
>     chosen as a non-prime, the sequence is not very arbitrary,
>     therefore a prime is recommended. """
>
>     M = 99999989
>     A = 2760727302517
>
>     return str((A*id) % M).zfill(len(str(M)))
>
> The last problem with this is that I have no real mathematical proof for that 
> algorithm, that "id" never maps to one number more than once. However, I 
> simply tested this with a little program and it seems to work.
>
> If you use the ORM, don't forget to do a session.flush() after adding the 
> object to the session, as this will calculate the primary index. Then you can 
> simply set col_num = mk_arb_seq(primary_index).
>
> Best Regards,
> Hermann
>
>
>   


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to