在不同 python 模块之间共享 PonyORM 的数据库会话

Sharing PonyORM's db session across different python module

我最初开始了一个小的 python 项目(Python,Tkinter amd PonyORM),后来变得越来越大,这就是为什么我决定将代码(以前只有单个文件)分成几个模块(例如 main、form1、实体、数据库)。 Main 作为主控制器,例如 form1 可以包含一个 tkinter 框架,它可以用作用户可以输入数据的界面,实体包含 db.Enttiy 映射和 pony.Database 实例的数据库及其连接细节。我认为问题是在导入期间,我收到此错误 "pony.orm.core.ERDiagramError: Cannot define entity 'EmpInfo': database mapping has already been generated"。你能告诉我应该怎么做的任何现有代码吗?

可能您导入模块的顺序有误。任何包含实体定义的模块都应在 db.generate_mapping() 调用之前导入。

我认为您应该在输入 tk.mainloop() 之前调用 db.generate_mapping(),此时所有导入都已完成。

避免这种情况的一个好方法是,不要让 db.generate_mapping() 调用发生在模块的顶层代码中,而是让模块导出一个函数,在所有其他模块调用 db.generate_mapping() 之后调用 db.generate_mapping()已导入。

我使用的模式是将我所有的 db.Entity sub类 放入一个名为 model 的模块中,然后在 model.py 的底部是:

def setup():
    """ Set up the database """
    db.bind(**database_config, create_db=True)
    db.generate_mapping(create_tables=True)

这个函数是我的应用程序自己启动时调用的(也是负责设置database_config)。这样可以保证正确的导入和设置顺序。

db对象本身也属于这个model模块;如果我需要在其他地方使用它,我导入 model 并使用 model.db.

如果你想进一步分离(不同的模型 类 存在于不同的模块中)你可以拥有一个拥有 db 的模块,然后是你的独立模型模块,然后是第三个导入 db 和模型并提供 setup 功能的模块。例如,您的目录结构可能如下所示:

  • model/
    • __init__.py -- 导入所有模型子模块并提供 setup 函数
    • db.py -- 提供 db 对象本身和任何其他人需要的公共实体对象
    • form1.pyform2.py 等 -- 导入 db 并使用其数据库对象定义实体

然后您的主应用程序可以执行以下操作:

import model
model.setup()