I want to separate my model classes into separate files in a models directory. I would like to have a separate file for:
I'm not sure how to structure my project to make that happen.
I've tried putting my main imports into init.py in the directory and them importing those into the individual model files, but I don't know where to put my db.generate_mapping() so that all classes are available. I'm guessing this is a best practice for a large application. I've got about 150 tables in my app at this point.
Any help/pointers would be appreciated.
You can use the following project structure:
# /myproject
# settings.py
# main.py
# /models
# __init__.py
# base.py
# requisitions.py
# workorders.py
# sales_orders.py
settings.py
is a file with database settings:
# settings.py
db_params = {'provider': 'sqlite', 'filename': ':memory:'}
main.py
is a file when you start application. You put db.generate_mapping
here:
# 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()
Note that it is not necessary to implicitly import all models, as they are accessible as attributes of db
object (like db.User
)
You can put db
object in base.py
(or general.py
), where you define your core models:
# base.py
from pony import orm
db = orm.Database()
class User(db.Entity):
name = Required(str)
orders = Set('Order')
Note that in User
model I can refer to Order
model defined in another module. You can also write it as
orders = Set(lambda: db.Order)
Unfortunately, IDEs like PyCharm at this moment cannot recognize that db.Order
refers to specific Order
class. You can import and use Order
class directly, but in some cases it will lead to problem with cyclic imports.
In other model files you import db
from .base
:
# workorders.py
from pony import orm
from .base import db
class Order(db.Entity):
description = Optional(str)
user = Required('User')
In /models/__init__.py
you import all modules to ensure that all models classes are defined before generate_mapping
is called:
# /models/__init__.py
from .base import db
from . import workorders
...
And then you can write
from models import db
And access models as db
attributes like db.User
, db.Order
, etc.
If you want to refer models directly in your code instead of accessing them as db
attributes, you can import all models in __init__.py
:
# /models/__init__.py
from .base import db, User
from .workorders import Order
...
And then you can import model classes as:
from models import db, User, Order, ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With