python - 如何处理 Peewee 模型和应用程序控制器之间的交叉引用?
问题描述
在使用 Peewee 进行编码时,我想利用面向对象的编程风格。不幸的是,文档只给出了处理数据库连接的全局变量的提示。当我尝试利用 Model 和 Controller 对象(此时 View 并不重要)时,我遇到了错误,可能是因为相互交叉引用:
ImportError:无法从“应用程序”导入名称“应用程序”(C:\ [... src ...])
Peewee 要求将数据库处理程序放在抽象类定义中,如下所示:
class BaseModel(Model):
class Meta:
database = SqliteDatabase('../res/db.db', pragmas={'foreign_keys': 1})
好吧,问题是,我不能保持这样的 DB 处理程序。我正在为带有服务模块的独立 Windows 应用程序准备我的应用程序。出于这个原因,我想我需要在配置文件中存储 db 文件的绝对路径。因此,在模型开始加载数据库之前,我需要从控制器加载配置文件。
我所做的是将数据库处理程序推送到控制器中的静态字段:
from Application import Application
from peewee import *
class BaseModel(Model):
class Meta:
database = Application.database
如您所见,数据库处理程序取自Application
抽象控制器。Application
是一个基本控制器,从中派生GuiApp
和ServiceApp
。两个后代都使用相同的数据库,因此将处理程序保留为静态字段对我来说看起来很方便。
现在,请看一下我的应用程序类:
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 实体导入放在我开始使用它们的地方之前,我的意思是,在__init__
方法内部,我不知何故失去了应用程序其他部分的可访问性。它迫使我将这个导入语句放在每个控制器方法中,以便正确访问实体模型。
另一方面,当我将实体导入放在控制器模块之上时,我从交叉引用中得到错误。我在上面放的错误消息。
总而言之,我正在寻找使用 peewee 模型管理应用程序的 OOP 方式。你知道有什么办法吗?还是我必须在应用程序初始化中使用全局数据库变量?
解决方案
感谢@coleifer,我决定为数据库处理创建另一个类:
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)
好吧,最终它看起来与全局变量非常相似,但我认为这个解决方案符合我的需求。最重要的是,我设法摆脱了交叉引用。
推荐阅读
- python - 机器学习和 SVM
- css - 确保在 Google pagespeed 洞察报告中未解决 webfont 加载期间文本保持可见
- inner-join - 使用 FOR ALL ENTRIES 连接各种表
- drupal - 如何更改临时 URL - RHEL 和 Drupal 7
- java - 如何使用 danielwegener Kafka appender 在 Kafka 消息中自定义 ZonedDateatime
- javascript - 使用离子(角度)。无法访问在显示屏/屏幕内有按钮的移动设备的硬件后退按钮
- swift - 如何使用以下示例修改gridView
- ios - 在 IOS 中使用 MucSub 获取 MUC 消息历史记录
- python - 使用 python 和 oracle db 在文件中获取、分离和写入相应数据的最快方法
- c++ - 堆栈变量的地址不断变化