【问题标题】:Pass database parameter into peewee Meta class将数据库参数传递给 peewee Meta 类
【发布时间】:2018-06-13 04:58:36
【问题描述】:

我正在使用peewee 来管理 Postgres 数据库上的 CRUD 操作。

the project documentation 中,应通过Meta 类设置与数据库的连接和创建ORM,其他ORM 类型应继承该类。

from peewee import *
db = PostgresqlDatabase('table', **{})

class BaseModel(Model):
    class Meta:
        database = db
class Product(BaseModel):
    name = CharField(unique=True)

我希望能够将此设置封装在 Persistence 类中,如下所示(以免创建任何全局变量):

class Persistence():
    db = None

    class BaseModel(Model):
        class Meta:
            database = Persistence.db
    class Product(BaseModel):
        name = CharField(unique=True)

    def __init__(self):
        self.db = PostgresqlDatabase('table', **{})

不幸的是,这不适用于:

AttributeError: type object 'Persistence' has no attribute 'db'

我认为这不会按预期工作(忽略AttributeError),因为即使在创建BaseModel 时变量在范围内,它也会是None 并且不会改变Persistence 类已实例化。

  1. 有没有办法正确确定db 变量的范围,以便它使用Persistence 上的类属性?
  2. 我可以通过其他机制将这个db 连接传递给peewee 吗?

【问题讨论】:

    标签: python peewee scoping


    【解决方案1】:

    您的问题混淆了两个独立的问题。 Python 作用域和 Peewee 数据库初始化。如果您清楚问题的具体出处,将会很有帮助。

    对于问题的 peewee 部分,您可能希望推迟数据库的初始化。为此,您需要创建一个数据库对象占位符 - 或使用 Proxy,具体取决于您希望延迟多长时间。

    延迟初始化示例:

    db = SqliteDatabase(None)
    
    class BaseModel(Model):
        class Meta:
            database = db
    
    # Declare other models as subclasses of BaseModel, e.g.
    class Foo(BaseModel):
        data = TextField()
    
    class Persistence(object):
        def __init__(self, db_file):
            db.init(db_file)
    

    您也可以使用代理,此处记录了该代理:http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database

    【讨论】:

      【解决方案2】:

      您可以利用“使用”执行上下文来建立动态数据库连接。例如我有这样的事情:

      from peewee import *
      from playhouse.shortcuts import RetryOperationalError
      
      from config import settings
      
      class RetryMySQLDatabase(RetryOperationalError, MySQLDatabase):
          pass
      
      db_connection = {}
      for conn in settings.DB:
          dbs = settings.DB[conn]
          db_connection[conn] = RetryMySQLDatabase(
                                      dbs["DB_NAME"], 
                                      host=dbs["DB_HOST"], 
                                      user=dbs["DB_USER"], 
                                      password=dbs["DB_PASS"]
                                  )
      
      db = db_connection["default"] #if you don't want to have default connection, you can make use of Proxy() here
      
      class BaseModel(Model):
          class Meta:
              database = db
      
      class Booking(BaseModel):
          id = BigIntegerField(db_column='ID', primary_key=True)
          name = CharField(db_column='NAME', null=True)
      

      而且,在使用模型类时,您可以指定要使用的数据库连接:

      with Using(db_connection["read_only"], [Booking]):
          booking_data = Booking.get(Booking.id == 123)
      

      参考:

      '使用'执行上下文:http://docs.peewee-orm.com/en/2.10.2/peewee/database.html?highlight=re#using-multiple-databases

      代理类:http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database

      【讨论】:

      • 引用过时的 api。
      猜你喜欢
      • 2018-07-08
      • 1970-01-01
      • 2013-04-02
      • 2020-11-26
      • 2013-01-08
      • 1970-01-01
      • 2022-07-22
      • 2021-07-30
      • 1970-01-01
      相关资源
      最近更新 更多