I define a lot of model classes using peewee. ClassName.create_table()
can generate the table,but only one table. How could I create all tables using a single statement?

- 6,335
- 8
- 31
- 43

- 133
- 1
- 1
- 5
7 Answers
Peewee has a helper that will create the tables in the correct order, but you still need to explicitly pass in all the models:
from peewee import *
db = SqliteDatabase(':memory:')
db.create_tables([ModelA, ModelB, ModelC])

- 24,887
- 6
- 60
- 75
-
1Maybe this function's docstring could appear in the API docs? – Cilyan Feb 07 '14 at 15:50
An update for Python 3 (and everyone who comes across this question via Google like I did). If you have all models based on the main peewee Model class you can simply use:
import peewee
models = peewee.Model.__subclasses__()
Credit to this question for the idea. They also go into more detail on how to get it to work recursively if your model is more complex.

- 1
- 1

- 327
- 2
- 10
-
2
-
Fails in some instances, e.g. if using the `SqliteQueueDatabase` extension, you get an `ImproperlyConfigured` error for the `VirtualModel` model, which is used internally but not actually part of your database. – fdmillion Jan 26 '22 at 07:41
Extending coleifer's answer with the assumption that all tables are grouped in one module:
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)

- 7,883
- 1
- 29
- 37
This snipnet will create all tables which objects are defined in the current module:
import sys
for cls in sys.modules[__name__].__dict__.values():
try:
if BaseModel in cls.__bases__:
cls.create_table()
except:
pass

- 6,637
- 2
- 43
- 49
for cls in globals().values():
if type(cls) == peewee.BaseModel:
try:
cls.create_table()
except peewee.OperationalError as e:
print(e)

- 12,771
- 5
- 30
- 36
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()
This also works for ManyToManyField's get_through_model()
.

- 1,918
- 1
- 20
- 31
I found the existing answers did not support the BaseModel pattern recommended in the docs. I created a helper function to recursively find Models
def all_subclasses(base: type) -> list[type]:
return [
cls
for sub in base.__subclasses__()
for cls in [sub] + all_subclasses(sub)
]
I then filtered out base models, by prefixing them with an underscore.
class _BaseModel(Model):
class Meta:
database = db
models = [
sub for sub in all_subclasses(Model)
if not sub.__name__.startswith('_')
]
db.create_tables(models)

- 3,115
- 3
- 23
- 36