11

我使用 peewee 定义了很多模型类。ClassName.create_table()可以生成表,但只能生成一张表。如何使用单个语句创建所有表?

4

7 回答 7

17

Peewee 有一个助手可以按正确的顺序创建表格,但您仍然需要显式传入所有模型:

from peewee import *
db = SqliteDatabase(':memory:')
db.create_tables([ModelA, ModelB, ModelC])
于 2014-02-07T15:40:10.223 回答
12

Python 3 的更新(以及像我一样通过谷歌遇到这个问题的每个人)。如果您拥有基于主要 peewee Model 类的所有模型,则可以简单地使用:

import peewee    
models = peewee.Model.__subclasses__()

归功于这个问题的想法。如果您的模型更复杂,他们还详细介绍了如何使其递归工作。

于 2017-05-06T13:14:11.063 回答
10

假设所有表都分组在一个模块中,从而扩展 coleifer 的答案:

import inspect
import peewee
import tables
models = [
    obj for name, obj in inspect.getmembers(
        tables, lambda obj: type(obj) == type and issubclass(obj, peewee.Model)
    )
]
peewee.create_model_tables(models)
于 2014-02-07T16:13:05.293 回答
2

这个snipnet将创建在当前模块中定义了对象的所有表:

import sys

for cls in sys.modules[__name__].__dict__.values():
    try:
        if BaseModel in cls.__bases__:
            cls.create_table()
    except:
        pass
于 2014-06-30T06:34:55.093 回答
2
for cls in globals().values():
    if type(cls) == peewee.BaseModel:
        try:
            cls.create_table()
        except peewee.OperationalError as e:
            print(e)
于 2016-03-27T12:09:42.507 回答
1
def create_all_tables():
    for cls in sys.modules[__name__].__dict__.values():
        if hasattr(cls, '__bases__') and issubclass(cls, peewee.Model):
            if cls is not BaseModel:
                cls.create_table()

这也适用于 ManyToManyField 的get_through_model()

于 2018-10-03T12:26:02.873 回答
0

我发现现有答案不支持文档中推荐的 BaseModel模式。我创建了一个辅助函数来递归查找模型

def all_subclasses(base: type) -> list[type]:
    return [
        cls
        for sub in base.__subclasses__()
        for cls in [sub] + all_subclasses(sub)
    ]

然后,我通过在它们前面加上下划线来过滤掉基本模型。

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

models = [
    sub for sub in all_subclasses(Model)
    if not sub.__name__.startswith('_')
]

db.create_tables(models)
于 2021-10-21T16:26:43.207 回答