Thanks Mike for the response. Comments below.

On Sep 27, 6:47 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On Sep 27, 2009, at 4:11 AM, nkhalasi wrote:
>
> in theory, you want to say session.flush() so that "n.next_id" is  
> persisted but the transaction is not committed.
>
> However the approach you have above wont work in any case assuming  
> the INSERT itself takes place within Session.flush() - the reentrant  
> call to flush should be raising an error immediately.  maybe you're  
> on an older SQLA version that doesn't raise this assertion which is  
> why it chokes later on the double commits (which is again, an  
> assertion that something isnt being called in the proper sequence).
>
> you don't want to be using the ORM layer within a Column default  
> generator.    Just the inefficiency alone of retrieiving an entire  
> object and doing a whole flush for every row in an enclosing series  
> of inserts makes it a bad idea.   do this instead:
>
> def get_next_id(context):
>      r = context.connection.execute(select([pk_generator_table]).where
> (pk_genrator_table.c.table_name=='principals'))
>      row = r.fetchone()
>      if row:
>          id = row['next_id']
>          if id > row['end_id']:
>              raise Exception(...)
>          context.connection.execute(pk_generator_table.update().where
> (pk_genrator_table.c.table_name=='principals').values
> (next_id=pk_generator_table.c.next_id + 1))
>          return id
>      else:
>          raise Exception(...)
>
> the above will get you out the door but still does a lot of work, if  
> you had a large volume INSERTs.   Ideally you'd use a MySQL stored  
> procedure or trigger to generate the new values, SQLAlchemy would  
> just fetch the new values after the fact.
>

I had tried this (which is similar to what you described above)
def newid(ctx):
    log.debug('generator.newid() invoked with context = %s' %ctx)
    id = ctx.connection.execute(select([pkgt.c.next_id],
                            pkgt.c.table_name=='principals',
for_update=True)).scalar()
    log.debug('Complied? %s, Autocommit? %s' %(ctx.compiled,
ctx.should_autocommit))
    ctx.connection.execute(pkgt.update(values={pkgt.c.next_id :
pkgt.c.next_id +1}))
    log.debug('Finished writing back the next id')
    return id

However with this I am getting unwanted commits. Essentially when the
newid(ctx) function executes the update it also does an commit which
results into my data committed which I would have otherwise expected
to be committed at some other point. I am trying to figure out how can
this update of next ID be done along with my regular application logic
commit.

Also what I am doing here is just a dummy hook. So my final version
will be lot more different.

Regards,
Naresh
--~--~---------~--~----~------------~-------~--~----~
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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to