我花了一段时间,但我想出了如何使用SQLAlchemy在两种不同类型的数据库之间建立关系模型:
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)
# Because the TERM table is in Oracle, but the SURVEY table is in
# MySQL, I can't rely on SQLAlchemy's ForeignKey. Thus,
# I need to specify the relationship entirely by hand, like so:
term = relationship("Term",
primaryjoin="Term.term_id==Survey.term_id",
foreign_keys=[term_id],
backref="surveys"
)
class Term(Base):
__tablename__ = 'TERM'
term_id = Column(Integer, primary_key=True)
term_name = Column(String(30))
start_date = Column(Date)
end_date = Column(Date)
mysql_engine = create_engine(MYSQL)
oracle_engine = create_engine(ORACLE)
Session = scoped_session(sessionmaker(
binds={
Term: oracle_engine,
Survey: mysql_engine
}
))
if __name__ == "__main__":
survey = Session.query(Survey).filter_by(survey_id=8).one()
print survey.term
print survey.term.surveys我必须这样做,因为term表在Oracle数据库中,我只能阅读access,而且我正在编写一个应用程序,它记录学生对该术语的调查。
上面的方法是可行的,但是当表的数量上升时,它是非常脆弱的,因为会话需要精确地指定哪个映射的类对应于哪个引擎。我非常希望能够使用不同的Base来定义哪些表属于哪个引擎,而不是单独绑定每个表。如下所示:
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不幸的是,这会导致查询运行时出现以下错误:
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.
即使我在定义了术语之后,也将此关系()添加到了调查中。
有人有什么建议吗?
发布于 2011-09-15 20:37:12
不能。AFAIK没有针对两个不同数据库的单一查询。此外,您的模型必须共享要在同一个查询中使用的相同元数据实例。
也许您可以通过ODBC将Oracle链接到db层的MySQL db,然后只与MySQL对话。我从来没有这样做过,我也不知道它是如何工作的。
您还可以独立地查询两个数据库,并在应用程序层上筛选和选择数据,以工作量较小者为准。
发布于 2015-09-27 16:50:50
这个答复可能很晚,但您可以将元数据与声明基分开定义,然后将其传递给这两个元数据。ie:
meta = MetaData()
mysql_engine = create_engine(MYSQL)
oracle_engine = create_engine(ORACLE)
MySQLBase = declarative_base(bind=mysql_engine, metadata=meta)
OracleBase = declarative_base(bind=oracle_engine, metadata=meta)https://stackoverflow.com/questions/7410010
复制相似问题