DocsFormularios y datos
Bases de datos
nx new puede estructurar una capa de modelo con SQLModel, SQLAlchemy o Tortoise-ORM. Nexy no envuelve el ORM: lo usa directamente, desde controladores y páginas.
Lo que añade el andamio
| Archivo | Propósito |
|---|---|
src/configs/db.py |
el motor (SQLModel, SQLAlchemy) o la configuración TORTOISE_ORM |
src/models/ |
clases de modelo |
src/services/ |
funciones que consultan los modelos |
.env |
DATABASE_URL, escrito cuando proporcionas la URL de una base de datos durante nx new |
La cadena de conexión proviene de la variable de entorno DATABASE_URL. Cuando no está configurado, el motor con scaffolding recurre a un archivo SQLite local, dev.db.
Usar un servicio en una página
from src.services.user_service import UserServiceusers = UserService.get_all()<ul> {% for user in users %} <li>{{ user.name }}</li> {% endfor %}</ul>Utilice un servicio en un controlador API
from src.services.user_service import UserService async def GET(): return UserService.get_all()Un controlador llama al servicio y pasa las filas a su vista o las devuelve como JSON:
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()users: prop[list] = []<ul> {% for user in users %} <li>{{ user.name }}</li> {% endfor %}</ul>Tortoise-ORM es asíncrono
Una página se ejecuta en el bucle de eventos del servidor y no puede esperar, por lo que asyncio.run(...) falla allí con "no se puede llamar desde un bucle de eventos en ejecución". El andamio src/configs/db.py le da a Tortoise un bucle propio, en un hilo, y dos ayudantes que le envían una corrutina:
| donde estas | llamar | hace |
|---|---|---|
| código de sincronización, como una página | run(UserService.get_all()) |
lo ejecuta y devuelve el resultado |
| código asíncrono, como un controlador o un controlador | await arun(UserService.get_all()) |
Lo mismo, sin bloquear el servidor. |
from src.configs.db import runfrom src.services.user_service import UserServiceusers = run(UserService.get_all())Un controlador es asíncrono: espera el servicio hasta arun y la vista solo muestra las filas:
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 se conecta la primera vez que se llama a uno de ellos. Llame al modelo desde un async def (await UserModel.all() dentro de un servicio), no a nivel de módulo: una llamada fuera de una corrutina se ejecuta antes de que Tortoise se haya conectado.
Enumere todos los módulos que contienen modelos en TORTOISE_ORM (la entrada models de src/configs/db.py). El andamio enumera el modelo de usuario y aerich.models; No se encuentra un modelo en un módulo que no está en la lista.
Migraciones
nx migrate elige la herramienta para tu ORM: Alembic para SQLModel y SQLAlchemy, Aerich para Tortoise-ORM.
| Comando | hace |
|---|---|
nx migrate --init |
inicializar la herramienta de migración para el proyecto |
nx migrate -m "add users" |
crear una migración a partir de los cambios de su modelo |
nx migrate --upgrade |
aplicar migraciones pendientes |
Con Aerich, el primer nx migrate ejecuta aerich init-db, lo que crea la primera migración y las tablas juntas; los siguientes ejecutan aerich migrate --name "..." y --upgrade ejecutan aerich upgrade.
nx migrate se detiene con un mensaje claro cuando falta DATABASE_URL o no se puede acceder a la base de datos (Alembic solamente: Aerich informa sus propios errores).
La primera migración está hecha para ti.
Cuando elige un ORM y proporciona una URL de base de datos, nx new configura la herramienta de migración, crea la primera migración y la aplica, por lo que la página de usuarios responde en la primera nexy dev. La herramienta de migración (alembic o aerich) se instala en el proyecto con el ORM.
Si la base de datos no responde (un servidor PostgreSQL que no se está ejecutando, falta un controlador), nx new dice el motivo, omite la migración y enumera los dos comandos que se ejecutarán cuando esté listo:
nexy migrate -m "create tables"nexy migrate --upgrade
Hasta que existan las tablas, una página que lee la base de datos falla con "no existe tal tabla".
Agregar un modelo
Alembic compara la base de datos con los modelos que alembic/env.py importa. Un modelo en un módulo nuevo no se ve hasta que ese módulo se importa allí, junto al modelo de usuario:
import src.models.user_model # noqa: F401import src.models.post_model # noqa: F401Para Tortoise-ORM, enumere el módulo en TORTOISE_ORM (ver arriba).
Próximos pasos
- Pruebas: prueba los controladores contra una base de datos temporal
- Configuración
- Implementar: establecer
DATABASE_URLen producción