2010-10-27 65 views
1

我有,目前看起来有点像这样的SQLAlchemy的ORM模型:如何在多个数据库和模式上重新使用sqlalchemy ORM模型?

Base = declarative_base() 

class Database(Base): 

    __tablename__ = "databases" 
    __table_args__ = (
    saschema.PrimaryKeyConstraint('db', 'role'), 
    { 
     'schema' : 'defines', 
     }, 
    ) 


    db = Column(String, nullable=False) 
    role = Column(String, nullable=False) 
    server = Column(String) 

事情是这样的,在实践中在多个数据库中存在这种模式,并在这些数据库,它会在多发模式存在。对于任何一个操作,我将只使用一个(database, schema)元组。

现在,我可以设置使用该数据库引擎:

Session = scoped_session(sessionmaker()) 
Session.configure(bind=my_db_engine) 
# ... do my operations on the model here. 

但我不知道我怎样才能改变__table_args__在执行时,这样的模式将是正确的。

+0

在完成任何查询之前,您是否知道所需的数据库和模式? – 2010-11-02 21:34:13

+0

否;数据库的名称和架构是来自另一个数据库的另一个模型中的字段。我首先找到那些,然后我想将此模型的一个实例关联到该连接。 – 2010-11-02 22:20:06

+1

你有没有找到一个可行的解决方案呢?我也有一个拥有多个模式的数据库,每个数据库都有一组相同的表,我希望能够在查询时或在会话级别设置模式。 – andyortlieb 2013-06-12 14:32:12

回答

0

一个选择是使用create_engine将模型绑定到模式/数据库,而不是在实际数据库中这样做。

#first connect to the database that holds the DB and schema 
engine1 = create_engine('mysql://user:[email protected]/schema1') 

Session = session(sessionmaker()) 
session = Session(bind=engine1) 

#fetch the first database 
database = session.query(Database).first() 

engine2 = create_engine('mysql://user:[email protected]%s/%s' % (database.DB, database.schema)) 
session2 = Session(bind=engine2) 

我不知道这是理想的,但它是一种方法。如果您事先缓存数据库列表,那么在大多数情况下,您只需创建一个会话。

1

我也在为这个问题寻找一个优雅的解决方案。如果有标准表/模型,但是在运行时有不同的表名,数据库和模式,这是如何处理的?其他人则建议编写一些函数来获取表名和模式参数,并为您构建模型。我发现使用__abstract__有帮助。我建议了一个可能有用的解决方案here。它涉及将具有特定模式/元数据的Base添加到继承中。

相关问题