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 theenvas an application session. - Wrap the model creation code (for all model classes) into a function and pass the
dbas 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
dbas 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 thedbconnection instance along the model tree. - Make
dba class attribute ofBaseModelwhich 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