Thanks Mike for the response. Comments below.
On Sep 27, 6:47 pm, Michael Bayer <[email protected]> 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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---