将数据库参数传递给peewee Meta类

时间:2018-06-04 04:54:25

标签: python peewee scoping

我正在使用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时在范围内,它也会{ {1}}并且在实例化None类时不会更改。

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

2 个答案:

答案 0 :(得分:0)

您的问题混淆了两个不同的问题。 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

答案 1 :(得分:-1)

您可以使用'使用'执行上下文以具有动态数据库连接。例如,我有这样的事情:

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