Hi,

I need to use dynamic table names in a project (though for the same
object). Now I got the following problem:
- I fetch data from an RSS feed to fill my database. Its an RSS feed
with many pages, each page has around 100 items
- I fetch the first page and create a table + mapper for a dynamic id
(called "my_id" below)
- then I do session.add and session.commit for each item in the feed,
everything ok so far
- after I fetch the second page ("my_id" is the same), I attempt to
recreate table and mapper (see code below) or simply readd them if
they already exist, that seems working as well
- I do the same for each item in the feed as the first time, but this
time it raise the following exception:
"sqlalchemy.orm.exc.FlushError: Instance <MyModel at 0x1bc1590> has a
NULL identity key.  Check if this flush is occuring at an
inappropriate time, such as during a load operation."

Here my data model (simplified) and the code to simply save a new item
from the feed:

===
import sqlalchemy
from sqlalchemy import import orm

mymetadata = sqlalchemy.MetaData()

class MyModel(object):
    def __init__(self, **kwargs):
        title = kwargs.get('title')
        body = kwargs.get('body')

class MyModelTable(object):
    def __init__(self, my_id):
        metadata = mymetadata
        table_name = 'mymodel_%s' % my_id
        self.table = sqlalchemy.Table(table_name, metadata,
            sqlalchemy.Column('id', sqlalchemy.Integer,
primary_key=True),
            sqlalchemy.Column('title', sqlalchemy.String(255),
index=True),
            sqlalchemy.Column('body', sqlalchemy.Text),
        useexisiting=True)
        self.table.create(get_engine(), checkfirst=True) #get_engine()
is helper function to retrieve the engine (not listed here)
        orm.mapper(MyModel, self.table)

def save_items(my_id, items): #assuming items is already parsed and
saved in a list
    model_table = MyModelTable(my_id)
    session = orm.sessionmaker(bind=get_engine(), autocommit=False,
                                    autoflush=True)
    for item in items:
        item_data = dict(title=item['title'],
body=item['description'])
        new_model_instance = MyModel(**item_data)
        session.add(new_model_instance)
    session.commit()
    session.close()
    orm.clear_mappers() #to avoid the exception when mapping the same
object to anoher ot the same table
===

Here is the whole traceback after the commit:
===
File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.5-
py2.6.egg/sqlalchemy/orm/session.py", line 623, in commit
    self.transaction.commit()
  File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.5-
py2.6.egg/sqlalchemy/orm/session.py", line 385, in commit
    self._prepare_impl()
  File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.5-
py2.6.egg/sqlalchemy/orm/session.py", line 369, in _prepare_impl
    self.session.flush()
  File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.5-
py2.6.egg/sqlalchemy/orm/session.py", line 1397, in flush
    self._flush(objects)
  File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.5-
py2.6.egg/sqlalchemy/orm/session.py", line 1487, in _flush
    flush_context.finalize_flush_changes()
  File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.5-
py2.6.egg/sqlalchemy/orm/unitofwork.py", line 320, in
finalize_flush_changes
    self.session._register_newly_persistent(state)
  File "/usr/local/lib/python2.6/dist-packages/SQLAlchemy-0.6.5-
py2.6.egg/sqlalchemy/orm/session.py", line 1056, in
_register_newly_persistent
    'operation.' % mapperutil.state_str(state))
sqlalchemy.orm.exc.FlushError: Instance <MyModel at 0x1bc1590> has a
NULL identity key.  Check if this flush is occuring at an
inappropriate time, such as during a load operation.
===

save_items() is called each time a new page is fetched (either for the
same "my_id") or another one.
This FlushError only happens when I have more than one page for the
same "my_id" and they are saved one after another. I also never
happens for the first page, neither for different "my_id"'s when
staying with one page.
According to the release notes of SQLAlchemy 0.6.5 this exception
raises when
===
"Added an assertion during flush which ensures
that no NULL-holding identity keys were generated
on "newly persistent" objects.
This can occur when user defined code inadvertently
triggers flushes on not-fully-loaded objects. "
===
Though I don't see  why it happens in my example.  I appreaciate any
help.  Thanks

-- 
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.

Reply via email to