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.

Reply via email to