在类中声明PeeWee模型,将数据库参数传递给BaseModel

时间:2018-01-29 13:30:04

标签: python peewee

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

因此会有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,因此第二个代码块将作为第一个代码块同样工作?

2 个答案:

答案 0 :(得分:0)

我不认为你是对的。当您声明self时,DataSaver仍然是database = self.db个实例。您是否有实际的错误?

答案 1 :(得分:0)

我知道,这个问题很旧,但是由于我自己研究了这个,因此这是我的解决方案。 您应该使用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变体复制内部类的定义。

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