I have the exact same issue. I create a new MetaData, use tometadata to copy the first to the second, and then if I use the second metadata it works fine. But if I pickle and unpickle it first then it doesn't work. So something about pickling/unpickling is breaking it.
On Monday, February 24, 2014 at 5:32:59 PM UTC-5, bkcsfi sfi wrote: > > I have a legacy database that I would like to use with automap > > unfortunately a number of tables each have multiple fks to the same table. > > Using docs at > http://docs.sqlalchemy.org/en/rel_0_9/orm/relationships.html#handling-multiple-join-paths > > and > > > http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html#specifying-classes-explcitly > > I thought I could define just some of the relationships before calling > base.prepare(), but that's not working for me. > > First, because reflection takes a long time on my database, I am pickling > base.metadata and restoring it later for use > > e..g to store the meta-data > > def generate_metadata_from_engine(engine): > base = automap_base() > base.prepare(engine, reflect=True) > return base.metadata > > > def store_metadata_to_file(metadata): > cPickle.dump(metadata, > file(get_metadata_path(), 'wb'), > cPickle.HIGHEST_PROTOCOL) > > > Later I restore it like this > > def get_unprepared_sqla_base(): > """load metadata from file and return auto-map base""" > return automap_base(metadata=load_metadata_from_file()) > > def load_metadata_from_file(): > return cPickle.load(file(get_metadata_path(), 'rb')) > > > Given a table in part like this: > > CREATE TABLE ORG > ( > DEFAULT_MANIFEST INTEGER, > RETURN_MANIFEST INTEGER > <snip> > ) > > ALTER TABLE ORG ADD CONSTRAINT C644ORG_DEFAULT_ > FOREIGN KEY (DEFAULT_MANIFEST) REFERENCES MANIFEST (ID) ON UPDATE > CASCADE ON DELETE SET NULL; > ALTER TABLE ORG ADD CONSTRAINT C644ORG_RETURN > FOREIGN KEY (RETURN_MANIFEST) REFERENCES MANIFEST (ID) ON UPDATE CASCADE > ON DELETE SET NULL; > > I have 2 fks to the manifest table > > > When running a query against the org table, I get this error > > sqlalchemy.exc.ArgumentError: Error creating backref 'org_collection' on > relationship 'org.org_collection': property of that name exists on mapper > 'Mapper|org|org' > > > It looks like the above error is actually on the manifest table, however > it's cleaner for me to define the relationship on the Org table and hope > that automap figures out the backref .. (not sure that works) > > So I'm trying this > > def test(): > engine = get_firebird_engine() > base = get_unprepared_sqla_base() > > class Org(base): > __tablename__ = 'org' > > default_manifest_collection = relationship('manifest', > foreign_keys="org.default_manifest") > current_manifest_collection = relationship('manifest', > foreign_keys="org.current_manifest") > > base.prepare() > session = get_session() > session.query(base.classes.org).first() > > > when I call test(), I now get this error:: > > Traceback (most recent call last): > File "database_metadata/test.py", line 46, in <module> > main(args=sys.argv[1:]) > File "database_metadata/test.py", line 39, in main > test() > File "database_metadata/test.py", line 25, in test > session.query(base.classes.org).first() > File > "/home/bkc/Python_Environments/mwd/local/lib/python2.7/site-packages/sqlalchemy/util/_collections.py", > > line 174, in __getattr__ > raise AttributeError(key) > AttributeError: org > > > If I comment out the definition of class Org in the test(), I go back to > getting the sqlalchemy.exc.ArgumentError: (though it's random which table > it fails on first) > > 1. am I correctly using pickled automap metadata? > > 2. does the existence of the Org class in base metadata break > base.prepare() because I'm not also reflecting from the database at that > time? > > 3. should I instead declare the Org class fragment before reflecting, and > then pickl'ing the meta-data with my modified org class will work? > > something else instead? > > Thanks > > > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.