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?
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)
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])
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.
SqliteQueueDatabase
extension, you get an ImproperlyConfigured
error for the VirtualModel
model, which is used internally but not actually part of your database. –
Neutron 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)
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
for cls in globals().values():
if type(cls) == peewee.BaseModel:
try:
cls.create_table()
except peewee.OperationalError as e:
print(e)
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()
.
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)
© 2022 - 2024 — McMap. All rights reserved.