It took me a while, but I figured out how to use SQLAlchemy to model the relationship between two different types of databases:
Base = declarative_base() class Survey(Base): __tablename__ = 'SURVEY' survey_id = Column("SURVEY_ID", Integer, primary_key=True) term_id = Column("TERM_ID", Integer, nullable=False)
I need to do this because the TERM table is in the Oracle database, on which I only have read access, and I am writing an application that records the polls made by students about this term.
The above works, but it is very fragile when the number of tables goes up, since the session must specify exactly which mapped classes correspond to which engine. I would really like to be able to use another Base to determine which tables belong to that engine, and not to bind each table separately. Like this:
mysql_engine = create_engine(MYSQL) oracle_engine = create_engine(ORACLE) MySQLBase = declarative_base(bind=mysql_engine) OracleBase = declarative_base(bind=oracle_engine) class Survey(MySQLBase): __tablename__ = 'SURVEY' survey_id = Column("SURVEY_ID", Integer, primary_key=True) term_id = Column("TERM_ID", Integer, nullable=False) class Term(OracleBase): __tablename__ = 'ads_term_v' term_id = Column(Integer, primary_key=True) term_name = Column(String(30)) start_date = Column(Date) end_date = Column(Date) Survey.term = relationship("Term", primaryjoin="Term.term_id==Survey.term_id", foreign_keys=[Survey.term_id], backref="surveys" ) Session = scoped_session(sessionmaker()) if __name__ == "__main__": survey = Session.query(Survey).filter_by(survey_id=8).one() print survey.term print survey.term.surveys
Unfortunately, this leads to the following error when executing the query:
sqlalchemy.exc.InvalidRequestError: When initializing mapper Mapper|Survey|SURVEY, expression 'Term.term_id==Survey.term_id' failed to locate a name ("name 'Term' is not defined"). If this is a class name, consider adding this relationship() to the <class '__main__.Survey'> class after both dependent classes have been defined.
although I did add a relation () to the survey after the term has been defined.
Does anyone have any suggestions?