如何在多个数据库和模式中重用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)
问题是,这个模型实际上存在于多个数据库中,而且在这些数据库里,它还会存在于多个模式(schema)下。对于任何一个操作,我只会使用一个 (数据库, 模式)
的组合。
现在,我可以通过以下方式设置数据库引擎:
Session = scoped_session(sessionmaker())
Session.configure(bind=my_db_engine)
# ... do my operations on the model here.
但是我不太确定在执行时如何更改 __table_args__
,以便让模式是正确的。
2 个回答
1
我也在寻找一个优雅的解决方案来处理这个问题。如果在运行时有标准的表格或模型,但表名、数据库和模式都不同,该怎么处理呢?其他人建议写一个函数,这个函数接受表名和模式作为参数,然后为你构建模型。我发现使用 __abstract__
是有帮助的。我在这里提出了一个可能有用的解决方案。这个方案涉及到在继承中添加一个具有特定模式/元数据的基础类。
1
一种选择是使用create_engine将模型绑定到一个模式或数据库,而不是直接在实际的数据库中进行绑定。
#first connect to the database that holds the DB and schema
engine1 = create_engine('mysql://user:pass@db.com/schema1')
Session = session(sessionmaker())
session = Session(bind=engine1)
#fetch the first database
database = session.query(Database).first()
engine2 = create_engine('mysql://user:pass@%s/%s' % (database.DB, database.schema))
session2 = Session(bind=engine2)
我不知道这是否是最好的方法,但这确实是一种可行的方式。如果你事先缓存好数据库的列表,那么在大多数情况下,你只需要创建一个会话。