【问题标题】:Declaring PeeWee models inside class, passing database parameter to BaseModel在类中声明 PeeWee 模型,将数据库参数传递给 BaseModel
【发布时间】:2018-07-08 05:14:42
【问题描述】:

我不确定我想做的事情是否合理,但我想将与数据库管理相关的所有类和方法放在一个类中。

所以会有DataSaver 类代表一个数据库实例。

现在,official PeeWee docs 建议创建 BaseModel 并在其中存储 database 变量。以下是它在示例中的显示方式:

from peewee import *

db = SqliteDatabase('my_app.db')

class BaseModel(Model):
    class Meta:
        database = db

class User(BaseModel):
    username = CharField(unique=True)

class Tweet(BaseModel):
    user = ForeignKeyField(User, backref='tweets')
    message = TextField()
    created_date = DateTimeField(default=datetime.datetime.now)
    is_published = BooleanField(default=True)

现在我正在尝试做同样的事情,但在课堂上:

class DataSaver:
    def __init__(self, database_save_path):
        self.database_save_path = database_save_path
        self.db = SqliteDatabase(database_save_path)
        db.connect()
        db.create_tables([User, Chat, Message], True)

    class BaseModel(Model):
        class Meta:
            database = self.db

    class User(BaseModel):
        name = CharField(unique=True)

    class Chat(BaseModel):
        name = CharField(unique=True)

这里的问题是:BaseModel 目前无权访问变量dbself 目前没有指向 DataSaver,所以很明显编译器在这一点上可能会有点困惑。

您知道如何将db 变量传递给 BaseModel,以便第二个代码块的工作方式与第一个相似吗?

【问题讨论】:

    标签: python peewee


    【解决方案1】:

    我不认为你是正确的。在您声明 database = self.db 时,self 仍然是 DataSaver 实例。您是否遇到了实际错误?

    【讨论】:

    • 他指的是BaseModel 的内部Meta 类中的database = self.db,实际上,selfMeta 实例的名称。我只是为了一个类似的问题来这里的,数据库需要只是一个静态类变量,所以我对原始问题没有答案。
    【解决方案2】:

    我知道,这个问题很老,但由于我自己研究过,所以这是我的解决方案。 您应该使用the peewee documentation

    中描述的技术之一
    class DataSaverA(object):
    
        def __init__(self, database_save_path):
            self.database_save_path = database_save_path
            self.db = SqliteDatabase(database_save_path)
    
            self.db.bind([DataSaverA.User, DataSaverA.Chat])
    
            self.db.connect()
            self.db.create_tables([DataSaverA.User, DataSaverA.Chat])
    
        class BaseModel(Model):
            pass
    
        class User(BaseModel):
            name = CharField(unique=True)
    
        class Chat(BaseModel):
            name = CharField(unique=True)
    

    这样,你可以例如有一个类DataSaverB,它需要声明自己的UserChat内部类,实例化用户喜欢

    u1 = DataSaverA.User.create(name='Uncle Bob')
    u2 = DataSaverB.User.create(name='Grandma L.')
    

    但是,我认为在这里使用内部类是不好的做法,因为您必须为所有 DataSaver 变体复制内部类的定义。

    就我而言,我更感兴趣的是对功能和配置进行分组,而不是实际依赖多个数据保存程序,因此我放弃了使用嵌套类的想法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-20
      • 2011-10-12
      • 1970-01-01
      • 1970-01-01
      • 2012-11-25
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多