Great, and to answer your TODO no, metadata.bind = engine is not necessary and I try to discourage people from using that activity by default (but the plethora of Turbogears and Pylons tutorials that keep using it makes this task more or less impossible). A discussion of that feature specifically is at http://www.sqlalchemy.org/docs/core/schema.html#binding-metadata-to-an-engine-or-connection .
On Aug 17, 2011, at 12:03 PM, Tim Black wrote: > Michael, > > Thank you for your advice. It took me a while to figure out how to follow > it, but in the end it worked. After reading the (excellent) SQLAlchemy docs > a lot more, and some other discussion group posts that explained the function > of the engine, metadata, and session objects, and reassured me it was > possible to have two databases, two engines, one metadata, and one session, I > figured out how to modify the TurboGears 2.1 multiple database setup (linked > below) to work that way. For others' reference, the essential modifications > to TurboGears' multiple databases setup (not including the necessary changes > to imports in model sub-modules) for making a relation between two databases > are below. > > Tim > > --- /tmp/bzr-diff-EWNNdM/old/projects/projects/model/__init__.py > +++ /tmp/bzr-diff-EWNNdM/new/projects/projects/model/__init__.py > @@ -12,16 +12,16 @@ > > -maker2 = sessionmaker(autoflush=True, autocommit=False, > - extension=ZopeTransactionExtension()) > -DBSession2 = scoped_session(maker2) > +#maker2 = sessionmaker(autoflush=True, autocommit=False, > +# extension=ZopeTransactionExtension()) > +#DBSession2 = scoped_session(maker2) > > -DeclarativeBase2 = declarative_base() > +#DeclarativeBase2 = declarative_base() > > @@ -35,11 +35,11 @@ > > -metadata2 = DeclarativeBase2.metadata > +#metadata2 = DeclarativeBase2.metadata > > @@ -49,10 +49,12 @@ > > def init_model(engine1, engine2): > """Call me before using any of the tables or classes in the model.""" > > # DBSession.configure(bind=engine) > DBSession.configure(bind=engine1) > - DBSession2.configure(bind=engine2) > + DBSession.configure(binds={Ticket:engine2}) > + #DBSession2.configure(bind=engine2) > > + # TODO: Is this statement necessary, since the engines are already > configured in the session? > metadata.bind = engine1 > - metadata2.bind = engine2 > + #metadata2.bind = engine2 > > On 08/13/2011 05:43 PM, Michael Bayer wrote: >> >> Do you have the "metadata" in Table shared with the metadata used by >> DeclarativeBase ? Otherwise the name "ticket" won't be located via the >> ForeignKey you're declaring in the WorkDone class. As an alternative you >> could link the ForeignKey to "ticket.c.id" but would be easier if you could >> use the "DeclarativeBase.metadata" for all table definitions. >> >> Otherwise yes you need to ensure that trac.py and main.py have both been >> imported before you attempt to use the mappings. >> >> >> On Aug 13, 2011, at 4:01 PM, Tim Black wrote: >> >>> I'm getting the following error message running TurboGears 2.1.1 and >>> SQLAlchemy 0.7.2, using TurboGears' multiple database setup described here: >>> http://turbogears.org/2.1/docs/main/MultipleDatabases.html. >>> Both databases are SQLite3 databases; one is the main database for the >>> TurboGears app; the other is a Trac 0.11.4 database. Can you help me >>> figure out what I'm doing wrong? >>> >>> InvalidRequestError: One or more mappers failed to initialize - can't >>> proceed with initialization of other mappers. Original exception was: When >>> initializing mapper Mapper|WorkDone|work_done, expression 'ticket' failed >>> to locate a name ("name 'ticket' is not defined"). If this is a class name, >>> consider adding this relationship() to the <class >>> 'projects.model.main.WorkDone'> class after both dependent classes have >>> been defined. >>> >>> In my model/__init__.py, I import the model objects in this order (the >>> traceback makes me think this is the right place to work--either I need to >>> change the import order here, or add the relation() after the final import, >>> but neither of these solutions have seemed to work): >>> >>> from projects.model.trac import ticket >>> from projects.model.main import WorkDone >>> # To follow the error message's instructions, I tried adding a relation() >>> here, but it generated a further error; maybe I didn't get the syntax right. >>> >>> If I should add a relation immediately above, what is the right syntax? >>> But this also seems like a hack to add a relation() here; if I have to add >>> a relation() here, does that mean my current code has circular dependencies? >>> >>> Here's the rest of my relevant code (with important items in bold): >>> >>> In projects/model/trac.py, I have the following (I haven't put any >>> relation() or backref in this table definition, because this file is >>> borrowed mostly unmodified from Trac's experimental SQLAlchemy model object >>> code, and I want to keep it that way): >>> >>> # begin Tim's modification >>> from projects.model import metadata2 >>> metadata = metadata2 >>> # end Tim's modification >>> >>> # Ticket system >>> ticket = Table('ticket', metadata, >>> Column('id', Integer, primary_key=True), >>> Column('type', Text), >>> Column('time', Integer, index=True), >>> Column('changetime', Integer), >>> Column('component', Text), >>> Column('severity', Text), >>> Column('priority', Text), >>> Column('owner', Text), >>> Column('reporter', Text), >>> Column('cc', Text), >>> Column('version', Text), >>> Column('milestone', Text), >>> Column('status', Text, index=True), >>> Column('resolution', Text), >>> Column('summary', Text), >>> Column('description', Text), >>> Column('keywords', Text)) >>> >>> In projects/model/main.py, I have: >>> >>> class WorkDone(DeclarativeBase): >>> __tablename__ = 'work_done' >>> id = Column(Integer, primary_key=True) >>> ticket_id = Column('ticket_id', Integer, ForeignKey('ticket.id')) # >>> many-to-one >>> ticket = relation('ticket', primaryjoin=ticket_id == 'ticket.id') >>> >>> The traceback is generated by line 105 of my projects/controllers/root.py, >>> which reads: >>> >>> for p in DBSession.query(model.Project): >>> >>> projects/model/main.py contains: >>> >>> class Project(DeclarativeBase): >>> id = Column(Integer, primary_key=True) >>> workDone = relation('WorkDone') # one-to-many >>> >>> ...and that same class contains several properties that reference the >>> WorkDone model object like this one does: >>> >>> @property >>> def totalHours(self): >>> return sum([w.elapsed for w in self.workDone]) >>> >>> Thank you for any help you can offer! >>> >>> Tim >>> >>> > > > -- > 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. -- 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.