如何处理 Peewee 模型和应用程序控制器之间的交叉引用?
How to handle cross referencing between Peewee model and application controller?
我想在使用 Peewee 编码时使用面向对象的编程风格。不幸的是,文档只给出了一些处理数据库连接的全局变量的提示。当我尝试使用 Model 和 Controller 对象(此时 View 并不重要)时,出现错误,可能是因为相互交叉引用:
ImportError: cannot import name 'Application' from 'Application'
(C:\ [... src ...] )
Peewee 需要将数据库处理程序放在抽象 class 定义中,如下所示:
class BaseModel(Model):
class Meta:
database = SqliteDatabase('../res/db.db', pragmas={'foreign_keys': 1})
好吧,问题是,我不能像那样保留数据库处理程序。我正在为带有服务模块的独立 Windows 应用程序准备我的应用程序。出于这个原因,我想我需要在配置文件中存储 db 文件的绝对路径。因此,在模型开始加载数据库之前,我需要从控制器加载配置文件。
我所做的是将数据库处理程序推送到控制器中的静态字段:
from Application import Application
from peewee import *
class BaseModel(Model):
class Meta:
database = Application.database
如您所见,数据库处理程序取自 Application
抽象控制器。 Application
是一个基本控制器,从中派生出 GuiApp
和 ServiceApp
。两个后代使用相同的数据库,因此将处理程序保留为静态字段对我来说看起来很方便。
现在,请看一下我的申请 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)
问题是,当我将 Peewee Entities import 放在我开始使用它们的地方之前时,我的意思是,在 __init__
方法内部,我不知何故失去了我应用程序其他部分的可访问性。它迫使我将此导入语句放入每个控制器方法中,以便正确访问实体模型。
另一方面,当我将实体导入放在控制器模块之上时,交叉引用出现错误。我在上面放的错误信息。
总而言之,我正在寻找使用 peewee 模型管理应用程序的 OOP 方法。你知道有什么办法吗?或者我必须在应用程序初始化中使用全局数据库变量吗?
感谢@coleifer,我决定再做一个class 用于数据库处理:
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)
好吧,最终它看起来与全局变量非常相似,但我认为这个解决方案符合我的需要。最重要的是,我设法摆脱了交叉引用。
我想在使用 Peewee 编码时使用面向对象的编程风格。不幸的是,文档只给出了一些处理数据库连接的全局变量的提示。当我尝试使用 Model 和 Controller 对象(此时 View 并不重要)时,出现错误,可能是因为相互交叉引用:
ImportError: cannot import name 'Application' from 'Application' (C:\ [... src ...] )
Peewee 需要将数据库处理程序放在抽象 class 定义中,如下所示:
class BaseModel(Model):
class Meta:
database = SqliteDatabase('../res/db.db', pragmas={'foreign_keys': 1})
好吧,问题是,我不能像那样保留数据库处理程序。我正在为带有服务模块的独立 Windows 应用程序准备我的应用程序。出于这个原因,我想我需要在配置文件中存储 db 文件的绝对路径。因此,在模型开始加载数据库之前,我需要从控制器加载配置文件。
我所做的是将数据库处理程序推送到控制器中的静态字段:
from Application import Application
from peewee import *
class BaseModel(Model):
class Meta:
database = Application.database
如您所见,数据库处理程序取自 Application
抽象控制器。 Application
是一个基本控制器,从中派生出 GuiApp
和 ServiceApp
。两个后代使用相同的数据库,因此将处理程序保留为静态字段对我来说看起来很方便。
现在,请看一下我的申请 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)
问题是,当我将 Peewee Entities import 放在我开始使用它们的地方之前时,我的意思是,在 __init__
方法内部,我不知何故失去了我应用程序其他部分的可访问性。它迫使我将此导入语句放入每个控制器方法中,以便正确访问实体模型。
另一方面,当我将实体导入放在控制器模块之上时,交叉引用出现错误。我在上面放的错误信息。
总而言之,我正在寻找使用 peewee 模型管理应用程序的 OOP 方法。你知道有什么办法吗?或者我必须在应用程序初始化中使用全局数据库变量吗?
感谢@coleifer,我决定再做一个class 用于数据库处理:
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)
好吧,最终它看起来与全局变量非常相似,但我认为这个解决方案符合我的需要。最重要的是,我设法摆脱了交叉引用。