PonyORM-多个模型文件

Jim*_*eil 4 python ponyorm

我想将我的模型类分离到models目录中的单独文件中。我想要一个单独的文件用于:

  • 常规(身份验证和全局类/表)
  • 申请单(用于申请单的表)
  • 工作单(用于工作单的表)
  • sales_orders(用于销售订单的表)
  • ...等等

我不确定如何组织我的项目来实现这一目标。

我尝试将主要导入文件放入目录的init .py中,并将它们导入各个模型文件中,但是我不知道将db.generate_mapping()放在哪里,以便所有类都可用。我猜想这是大型应用程序的最佳实践。此时,我的应用程序中大约有150张桌子。

任何帮助/指针将不胜感激。

Ale*_*sky 6

您可以使用以下项目结构:

# /myproject
#     settings.py
#     main.py
#     /models
#         __init__.py
#         base.py
#         requisitions.py
#         workorders.py
#         sales_orders.py
Run Code Online (Sandbox Code Playgroud)

settings.py 是具有数据库设置的文件:

# settings.py
db_params = {'provider': 'sqlite', 'filename': ':memory:'}
Run Code Online (Sandbox Code Playgroud)

main.py是启动应用程序时的文件。您放在db.generate_mapping这里:

# main.py
from pony import orm
import settings
from models import db
from your_favorite_web_framework import App

# orm.set_sql_degug(True)
db.bind(**settings.db_params)
db.generate_mapping(create_tables=True)

with orm.db_session:
    orm.select(u for u in db.User).show()

if __name__ == '__main__':
    app = App()
    app.run()
Run Code Online (Sandbox Code Playgroud)

请注意,不必隐式导入所有模型,因为它们可以作为dbobject的属性(例如db.User)进行访问

您可以将db对象放在base.py(或general.py)中,在其中定义核心模型:

# base.py
from pony import orm

db = orm.Database()

class User(db.Entity):
    name = Required(str)
    orders = Set('Order')
Run Code Online (Sandbox Code Playgroud)

请注意,在User模型中,我可以引用Order在另一个模块中定义的模型。你也可以写成

    orders = Set(lambda: db.Order)
Run Code Online (Sandbox Code Playgroud)

不幸的是,目前像PyCharm这样的IDE无法识别db.Order指向特定Order类的东西。您可以Order直接导入和使用类,但是在某些情况下,它将导致循环导入问题。

db从中导入的其他模型文件中.base

# workorders.py
from pony import orm
from .base import db

class Order(db.Entity):
    description = Optional(str)
    user = Required('User')
Run Code Online (Sandbox Code Playgroud)

/models/__init__.py导入所有模块以确保在generate_mapping调用之前定义了所有模型类之后:

# /models/__init__.py
from .base import db
from . import workorders
...
Run Code Online (Sandbox Code Playgroud)

然后你可以写

from models import db
Run Code Online (Sandbox Code Playgroud)

和访问模式的db属性,如db.Userdb.Order等。

如果要直接在代码中引用模型而不是将其作为db属性访问,则可以将所有模型导入__init__.py

# /models/__init__.py
from .base import db, User
from .workorders import Order
...
Run Code Online (Sandbox Code Playgroud)

然后可以将模型类导入为:

from models import db, User, Order, ...
Run Code Online (Sandbox Code Playgroud)