im assuming this is https://bitbucket.org/zzzeek/sqlalchemy/issues/3632/immutablecolumncollection-creates-a a fix is posted but I'm not comfortable merging in 1.0.x since it will break existing pickled metadata files.
On 01/20/2016 07:48 PM, Jeff Laughlin wrote: > 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 > > <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 > > <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 <http://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 <http://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 > <mailto:sqlalchemy+unsubscr...@googlegroups.com>. > To post to this group, send email to sqlalchemy@googlegroups.com > <mailto:sqlalchemy@googlegroups.com>. > Visit this group at https://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. -- 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.