如何在多个数据库和模式上重用sqlalchemy ORM模型?

时间:2010-10-27 20:02:56

标签: python orm sqlalchemy

我有一个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__,以便架构是正确的。

2 个答案:

答案 0 :(得分: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)

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

答案 1 :(得分:1)

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