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.

Reply via email to