I'm using Peewee as ORM provider for my Python 3.x projects. As suggested in their Quickstart page I go for the simple design where I define a model.py module containing all my model definitions e.g.
-------------------- model.py ---------------------
from peewee import *
from playhouse.db_url import connect
db = connect('sqlite:///some/folder/people.db')
class BaseModel(Model):
class Meta:
database = db # uses the "people.db" database
class Person(BaseModel):
name = CharField()
birthday = DateField()
----------------------------------------------------
basically db
has module scope and it's hard-coded. I will have multiple separate entry point main CLI or scripts that would like to set this db
differently e.g. UIT, UT and PROD different databases.
As I see it I have the following possible alternatives to "inject" the db
connection instance dynamically to my model:
- Use the process environment as a session to put and read the connection URL i.e.
os.environ['DATABASE'] = 'sqlite:///some/folder/people.db'
. This solution is ok-ish but seems a bit hacky to me abusing theenv
as an application session. - Wrap the model creation code (for all model classes) into a function and pass the
db
as parameter. This is cleaner but then I lose the module class import facility i.e. I can no longer dofrom model import Person
. - Have all model classes take the
db
as a constructor argument, even cleaner than the previous one but incurs into a lot of error-prone boilerplate code as all model classes would now need to define a constructor and pass thedb
connection instance along the model tree. - Make
db
a class attribute ofBaseModel
which can be set from the scripts then I don't know how it can be accessed from the nested class Meta.
For example:
class BaseModel(Model):
db = connect('sqlite:///some/folder/people.db') # default
class Meta:
database = db # doesn't see the enclosing's class attribute db
Aucun commentaire:
Enregistrer un commentaire