ДокументацияФормы и данные

Базы данных

nx new может формировать слой модели с помощью SQLModel, SQLAlchemy или Tortoise-ORM. Nexy не оборачивает ORM: вы используете его напрямую, из обработчиков и страниц.

Что дает эшафот

Файл Цель
src/configs/db.py двигатель (SQLModel, SQLAlchemy) или настройки TORTOISE_ORM
src/models/ классы моделей
src/services/ функции, которые опрашивают модели
.env DATABASE_URL, пишется, когда вы указываете URL-адрес базы данных во время nx new

Строка подключения берется из переменной среды DATABASE_URL. Если он не установлен, механизм формирования шаблонов возвращается к локальному файлу SQLite, dev.db.

Использовать услугу на странице

src/маршруты/пользователи/index.nexy
---from src.services.user_service import UserServiceusers = UserService.get_all()---<ul>  {% for user in users %}  <li>{{ user.name }}</li>  {% endfor %}</ul>

Использование службы в обработчике API

src/routes/api/users.py
from src.services.user_service import UserService  async def GET():    return UserService.get_all()

Контроллер вызывает службу и передает строки в ее представление или возвращает их в формате JSON:

src/apps/users/user_controller.py
from nexy.decorators import Controllerfrom nexy.hooks import useViews from src.services.user_service import UserService  @Controller("/users")class UserController:    async def get(self):        users = UserService.get_all()        return useViews("src/apps/users/user_view.nexy", context={"users": users})  @Controller("/api/users")class UserApiController:    async def get(self):        return UserService.get_all()
src/apps/users/user_view.nexy
---users: prop[list] = []---<ul>  {% for user in users %}  <li>{{ user.name }}</li>  {% endfor %}</ul>

Tortoise-ORM является асинхронным

Страница выполняется в цикле событий сервера и не может ее ожидать, поэтому asyncio.run(...) завершается сбоем с сообщением «невозможно вызвать из работающего цикла событий». Скаффолд src/configs/db.py дает Tortoise собственный цикл в одном потоке и двух помощников, которые отправляют ему сопрограмму:

Где ты Позвонить Делает
код синхронизации, например страница run(UserService.get_all()) запускает его и возвращает результат
асинхронный код, например обработчик или контроллер await arun(UserService.get_all()) то же самое, без блокировки сервера
src/маршруты/пользователи/index.nexy
---from src.configs.db import runfrom src.services.user_service import UserServiceusers = run(UserService.get_all())---

Контроллер является асинхронным: он ожидает обслуживания через arun, а представление показывает только строки:

src/apps/users/user_controller.py
from nexy.decorators import Controllerfrom nexy.hooks import useViews from src.configs.db import arunfrom src.services.user_service import UserService  @Controller("/users")class UserController:    async def get(self):        users = await arun(UserService.get_all())        return useViews("src/apps/users/user_view.nexy", context={"users": users})

Tortoise подключается при первом вызове одного из них. Вызов модели из async def (await UserModel.all() внутри службы), а не на уровне модуля: вызов вне сопрограммы выполняется до подключения Tortoise.

Перечислите все модули, содержащие модели в TORTOISE_ORM (запись models в src/configs/db.py). В шаблоне перечислены модель пользователя и aerich.models; модель в модуле, которого нет в списке, не найдена.

Миграции

nx migrate выбирает инструмент для вашего ORM: Alembic для SQLModel и SQLAlchemy, Aerich для Tortoise-ORM.

Команда Делает
nx migrate --init инициализировать инструмент миграции для проекта
nx migrate -m "add users" создайте миграцию из изменений вашей модели
nx migrate --upgrade применить ожидающие миграции

При использовании Aerich первый nx migrate запускает aerich init-db, который создает первую миграцию и таблицы вместе; следующие запускают aerich migrate --name "...", а --upgrade запускают aerich upgrade.

nx migrate останавливается с четким сообщением, когда DATABASE_URL отсутствует или база данных недоступна (только Alembic: Aerich сообщает о своих собственных ошибках).

Первая миграция сделана для вас

Когда вы выбираете ORM и указываете URL-адрес базы данных, nx new настраивает инструмент миграции, создает первую миграцию и применяет ее, поэтому страница пользователя отвечает на первую nexy dev. Инструмент миграции (alembic или aerich) устанавливается в проект вместе с ORM.

Если база данных не отвечает (сервер PostgreSQL не работает, отсутствует драйвер), nx new говорит, почему, пропускает миграцию и перечисляет две команды, которые нужно выполнить, когда она будет готова:

nexy migrate -m "create tables"nexy migrate --upgrade

Пока таблицы не существуют, страница, читающая базу данных, завершается с ошибкой «нет такой таблицы».

Добавить модель

Alembic сравнивает базу данных с моделями, которые alembic/env.py импортирует. Модель в новом модуле не видна до тех пор, пока этот модуль не будет импортирован туда, рядом с пользовательской моделью:

перегонный куб/env.py
import src.models.user_model  # noqa: F401import src.models.post_model  # noqa: F401

Для Tortoise-ORM вместо этого укажите модуль в TORTOISE_ORM (см. выше).

Следующие шаги

Изменить на GitHub

Enter открывает результат, Esc закрывает.