【问题标题】:How can I re-use a sqlalchemy ORM model on multiple databases and schemas?如何在多个数据库和模式上重用 sqlalchemy ORM 模型?
【发布时间】:2010-10-27 20:02:56
【问题描述】:

我有一个 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__ 以使架构成为正确的架构。

【问题讨论】:

  • 在进行任何查询之前,您知道所需的数据库和架构吗?
  • 否;数据库的名称和模式是来自另一个数据库的另一个模型中的字段。我先找到这些,然后我想将此模型的一个实例与该连接相关联。
  • 您找到了可行的解决方案吗?我还有一个包含许多模式的数据库,每个模式都有一组相同的表,我希望能够在查询时或在会话级别设置模式。

标签: python orm sqlalchemy


【解决方案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)

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      • 1970-01-01
      • 2011-03-05
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-02
      相关资源
      最近更新 更多