【问题标题】:Flask sqlalchemy model shared across multiple Oracle schemas跨多个 Oracle 模式共享的 Flask sqlalchemy 模型
【发布时间】:2020-04-13 02:01:21
【问题描述】:

我必须创建一个 Flask 应用程序,该应用程序需要从放置在同一个 Oracle 实例上的多个几乎相同的模式中读取数据。我只能通过“read_only”用户连接到这个数据库。 通过这样做,我正在使用蓝图。

project
|-warehouse01
|   -__init__.py 
|   - view.py
|-warehouse02
|   -__init__.py 
|   - view.py
|-warehouse999
|   -__init__.py 
|   - view.py
-model.py
run.py
config.py 

当然所有模式的模型都是相同的

class Product(db.Model):
    #__table_args__ = {'schema': 'warehouse01'}
    __tablename__ = 'PRODUCTS'
    prod_no = db.Column(db.Integer, primary_key=True, nullable=False)
    prod_name = db.Column(db.String(35), nullable=False)
    quantity = db.Column(db.Integer, nullable=False)
    ...
    steps = db.relationship('Shipment', backref='shipments', lazy='dynamic')

class Shipment(db.Model):
    __tablename__ = 'SHIPMENTS'
    #__table_args__ = {'schema': 'warehouse01'}
    shipm_no = db.Column(db.Integer,  ,  primary_key=True, nullable=False)
    prod_no = db.Column(db.Integer, db.ForeignKey('PRODUCTS.prod_no'), nullable=False)
    customer_id= db.Column(db.Integer, db.ForeignKey('CUSTOMERS.customer_id') nullable=False)
    ...


问题是通过不同的模式连接 (READ_ONLY) 我必须在 table_args 中声明一个模式 我想对所有模式使用相同的模型。显然我不想为所有蓝图创建单独的模型。 是否可以对所有模式使用相同的模型或在蓝图中重新定义模式名称?

【问题讨论】:

    标签: python oracle flask sqlalchemy schema


    【解决方案1】:

    我终于找到了一种方法来做到这一点。不幸的是,@Laurent LAPORTE 提出的方法不合适。仅当我在模型中只有一个类时,并且仅在添加 'extend_existing': True 后才有效。如果我错了,请纠正我,但在 Flask 中,数据库模型是在应用程序启动时声明的。由于架构名称是__table_args__ = {'schema': schema} 中声明的类的一部分,当您想更改架构时,SqlAlchemy 将其视为尝试在模型注册表中使用现有名称定义新类。

    我的解决方案是从 table_args 中删除架构并通过 sql 命令设置架构名称,如下所示: def estimate_schema(schema): db.engine.execute(f"alter session set current_schema={schema}")

    我在每条路线之前使用它并且它有效

    def index(): estimate_schema('warehouse01') ...

    【讨论】:

      【解决方案2】:

      我认为您可以使用工厂函数动态创建模型:

      def create_product_model(schema):
          class Product(db.Model):
              __table_args__ = {'schema': schema}
              __tablename__ = 'PRODUCTS'
              prod_no = db.Column(db.Integer, primary_key=True, nullable=False)
              prod_name = db.Column(db.String(35), nullable=False)
              quantity = db.Column(db.Integer, nullable=False)
              ...
              steps = db.relationship('Shipment', backref='shipments', lazy='dynamic')
      
          return Product
      

      【讨论】:

      • 这是不可能使用这种方法的。通过使用def index(): products = create_product_model('warehouse01) print(type(session.sess_no)) return 'test',您会收到
      • 为了让它工作,我必须添加__table_args__ = {'schema': schema, 'extend_existing': True}
      猜你喜欢
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 2015-04-29
      • 1970-01-01
      • 2016-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多