I would like to make use of object-oriented programming style when coding with Peewee. Unfortunately, docs give hints only with kinda global variables handling DB connection. When I try to take adventage of Model and Controller objects (View isn't important at this moment), I'm getting error, probably because of cross-referencing each other:
ImportError: cannot import name 'Application' from 'Application' (C:\ [... src ...] )
Peewee requires to put database handler in abstract class definition, like this:
class BaseModel(Model):
class Meta:
database = SqliteDatabase('../res/db.db', pragmas={'foreign_keys': 1})
Well, the problem is, I cannot keep the DB handler like that. I'm preparing my app for kinda standalone Windows application with service module. For this reason, I guess I need to store absolute path for db file in config file. Consequently, before the model starts loading database, I need to load configuration files from controller.
What I did was pushing the DB handler to the static field in controller:
from Application import Application
from peewee import *
class BaseModel(Model):
class Meta:
database = Application.database
As you see, DB handler is taken from Application
abstract controller. Application
is a base controller, from which derives GuiApp
and ServiceApp
. Both descendands use the same DB, so keeping handler as a static field looks convenient for me.
Now, please do take a look at my Application class:
import logging.handlers
from peewee import SqliteDatabase
import datetime
import threading
from Windows import *
class Application:
database = SqliteDatabase(None)
def __init__(self, appname):
# (...)
from Entities import RouterSettings, BalanceEntry
Application.database.init(
conig_app_src + 'db.db',
pragmas={'foreign_keys': 1})
Application.database.connect()
# !!!
from Entities import RouterSettings, BalanceEntry
# !!!
Application.database.create_tables([RouterSettings, BalanceEntry], safe=True)
The problem is, when I put Peewee Entities import right before the place I start using them, I mean, inside __init__
method, I'm somehow losing accessability from another parts of my app. It forces me to put this import statements in every controller method in order to get proper access to Entity models.
On the other hand, when I put Entity import on top of controller module, I'm getting error from cross referencing. Error message I put above.
To sum up, I'm looking for OOP way to manage app with peewee models. Do you know any way to do that? Or do I have to use global database variable in the app init?
Thanks to @coleifer, I decided to make one another class for database handling:
class DbHandler:
database = SqliteDatabase(None)
@staticmethod
def start(dbSrc):
DbHandler.database.init(
dbSrc + '\\res\\SIMail.db',
pragmas={'foreign_keys': 1})
DbHandler.database.connect()
DbHandler.database.create_tables([RouterSettings, BalanceEntry],
safe=True)
Well, eventually it looks quite similar to global variables, but I think this solution fits my needs. What is the most important, I managed to get out of cross-referencing.