Some checks failed
build-and-deploy / build-and-deploy (push) Failing after 1m47s
- Agregar PostgreSQL 16 con esquema completo - Crear API endpoints para lotes y operaciones - Implementar UI con Nuxt UI (tablas, formularios, trazabilidad) - Agregar datos de ejemplo del flujo completo - Documentar sistema en PLAN_TRAZABILIDAD.md
339 lines
7.7 KiB
Markdown
339 lines
7.7 KiB
Markdown
# Database - Scripts SQL
|
|
|
|
Este directorio contiene los scripts SQL para inicializar y gestionar la base de datos PostgreSQL del sistema de trazabilidad.
|
|
|
|
---
|
|
|
|
## Archivos
|
|
|
|
### `01_schema.sql`
|
|
Crea el esquema completo de la base de datos:
|
|
- Tablas: `lotes`, `operaciones`, `operacion_lotes`
|
|
- Índices para optimización
|
|
- Función `get_trazabilidad()` para queries recursivas
|
|
- Vista `vista_lotes_con_origen`
|
|
- Constraints y validaciones
|
|
|
|
### `02_seed.sql`
|
|
Datos de ejemplo que representan un flujo completo:
|
|
- Ingreso de uva (2086 kg)
|
|
- Despulpado → primera, segunda, rechazos
|
|
- Oreado (con error de registro)
|
|
- Ajuste de merma (1500 → 1480 kg)
|
|
- Ajuste de tipo (oreado → presecado)
|
|
- Reposo
|
|
- Secado final (mezcla de 2 lotes = 2000 kg)
|
|
|
|
---
|
|
|
|
## Ejecución Automática
|
|
|
|
Cuando usas **Docker Compose**, estos scripts se ejecutan automáticamente al iniciar PostgreSQL por primera vez gracias al montaje:
|
|
|
|
```yaml
|
|
volumes:
|
|
- ./nuxt4/server/database:/docker-entrypoint-initdb.d:ro
|
|
```
|
|
|
|
PostgreSQL ejecuta todos los archivos `.sql` en orden alfabético dentro de `/docker-entrypoint-initdb.d/`.
|
|
|
|
**Orden de ejecución:**
|
|
1. `01_schema.sql` - Crea estructura
|
|
2. `02_seed.sql` - Inserta datos de ejemplo
|
|
|
|
---
|
|
|
|
## Ejecución Manual
|
|
|
|
### Opción 1: Desde el contenedor Docker
|
|
|
|
```bash
|
|
# Conectarse al contenedor
|
|
docker exec -it seguidorDeLotes-postgres psql -U seguidor -d seguidor_lotes
|
|
|
|
# Dentro de psql, ejecutar:
|
|
\i /docker-entrypoint-initdb.d/01_schema.sql
|
|
\i /docker-entrypoint-initdb.d/02_seed.sql
|
|
```
|
|
|
|
### Opción 2: Desde tu máquina local
|
|
|
|
```bash
|
|
# Asegúrate de tener psql instalado
|
|
psql -h localhost -U seguidor -d seguidor_lotes -f 01_schema.sql
|
|
psql -h localhost -U seguidor -d seguidor_lotes -f 02_seed.sql
|
|
```
|
|
|
|
### Opción 3: Copiar y pegar en pgAdmin o DBeaver
|
|
|
|
Abre los archivos `.sql` en tu cliente SQL favorito y ejecútalos directamente.
|
|
|
|
---
|
|
|
|
## Reiniciar la Base de Datos
|
|
|
|
Si necesitas empezar desde cero:
|
|
|
|
```bash
|
|
# Detener contenedores y eliminar volúmenes
|
|
docker-compose down -v
|
|
|
|
# Volver a iniciar (ejecutará scripts automáticamente)
|
|
docker-compose up -d
|
|
|
|
# Ver logs para confirmar
|
|
docker logs -f seguidorDeLotes-postgres
|
|
```
|
|
|
|
---
|
|
|
|
## Verificar que todo está correcto
|
|
|
|
### 1. Conectarse a la base de datos
|
|
|
|
```bash
|
|
docker exec -it seguidorDeLotes-postgres psql -U seguidor -d seguidor_lotes
|
|
```
|
|
|
|
### 2. Listar tablas
|
|
|
|
```sql
|
|
\dt
|
|
```
|
|
|
|
**Deberías ver:**
|
|
```
|
|
List of relations
|
|
Schema | Name | Type | Owner
|
|
--------+------------------+-------+----------
|
|
public | lotes | table | seguidor
|
|
public | operacion_lotes | table | seguidor
|
|
public | operaciones | table | seguidor
|
|
```
|
|
|
|
### 3. Contar registros
|
|
|
|
```sql
|
|
SELECT
|
|
(SELECT COUNT(*) FROM lotes) as total_lotes,
|
|
(SELECT COUNT(*) FROM operaciones) as total_operaciones,
|
|
(SELECT COUNT(*) FROM operacion_lotes) as total_relaciones;
|
|
```
|
|
|
|
**Deberías ver algo como:**
|
|
```
|
|
total_lotes | total_operaciones | total_relaciones
|
|
-------------+-------------------+------------------
|
|
9 | 8 | 16
|
|
```
|
|
|
|
### 4. Ver lotes creados
|
|
|
|
```sql
|
|
SELECT codigo, tipo, cantidad_kg FROM lotes ORDER BY fecha_creado;
|
|
```
|
|
|
|
**Deberías ver:**
|
|
```
|
|
codigo | tipo | cantidad_kg
|
|
-----------+----------------------+-------------
|
|
UVA-001 | uva | 2086.00
|
|
PRIM-001 | despulpado_primera | 1500.00
|
|
SEG-001 | despulpado_segunda | 400.00
|
|
RECH-001 | despulpado_rechazos | 150.00
|
|
ORE-001 | oreado | 1500.00
|
|
ORE-001A | oreado | 1480.00
|
|
PRE-001 | presecado | 1480.00
|
|
REP-001 | reposo | 1480.00
|
|
REP-002 | reposo | 520.00
|
|
SEC-001 | secado | 2000.00
|
|
```
|
|
|
|
### 5. Probar la función de trazabilidad
|
|
|
|
```sql
|
|
SELECT * FROM get_trazabilidad(
|
|
(SELECT id FROM lotes WHERE codigo = 'SEC-001')
|
|
);
|
|
```
|
|
|
|
**Deberías ver:** Todo el historial del lote `SEC-001` desde el ingreso de uva.
|
|
|
|
---
|
|
|
|
## Estructura de las Tablas
|
|
|
|
### Tabla `lotes`
|
|
|
|
```sql
|
|
CREATE TABLE lotes (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
codigo TEXT UNIQUE,
|
|
tipo TEXT NOT NULL,
|
|
fecha_creado TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
lugar_id INTEGER,
|
|
cantidad_kg NUMERIC(10,2),
|
|
meta JSONB
|
|
);
|
|
```
|
|
|
|
### Tabla `operaciones`
|
|
|
|
```sql
|
|
CREATE TABLE operaciones (
|
|
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
|
|
tipo TEXT NOT NULL,
|
|
fecha TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
lugar_id INTEGER,
|
|
meta JSONB
|
|
);
|
|
```
|
|
|
|
### Tabla `operacion_lotes`
|
|
|
|
```sql
|
|
CREATE TABLE operacion_lotes (
|
|
operacion_id UUID NOT NULL REFERENCES operaciones(id) ON DELETE CASCADE,
|
|
lote_id UUID NOT NULL REFERENCES lotes(id) ON DELETE CASCADE,
|
|
rol TEXT NOT NULL CHECK (rol IN ('input', 'output')),
|
|
cantidad_kg NUMERIC(10,2),
|
|
PRIMARY KEY (operacion_id, lote_id, rol)
|
|
);
|
|
```
|
|
|
|
---
|
|
|
|
## Queries Útiles
|
|
|
|
### Ver todas las operaciones de un lote
|
|
|
|
```sql
|
|
SELECT
|
|
o.tipo AS operacion,
|
|
o.fecha,
|
|
ol.rol,
|
|
ol.cantidad_kg
|
|
FROM operacion_lotes ol
|
|
JOIN operaciones o ON o.id = ol.operacion_id
|
|
WHERE ol.lote_id = (SELECT id FROM lotes WHERE codigo = 'SEC-001')
|
|
ORDER BY o.fecha;
|
|
```
|
|
|
|
### Ver lotes que se usaron para crear un lote específico (inputs directos)
|
|
|
|
```sql
|
|
-- Inputs directos del lote SEC-001
|
|
SELECT
|
|
l.codigo,
|
|
l.tipo,
|
|
l.cantidad_kg,
|
|
o.tipo AS operacion_tipo
|
|
FROM lotes l
|
|
JOIN operacion_lotes ol_in ON ol_in.lote_id = l.id
|
|
JOIN operacion_lotes ol_out ON ol_out.operacion_id = ol_in.operacion_id
|
|
JOIN operaciones o ON o.id = ol_out.operacion_id
|
|
WHERE ol_out.lote_id = (SELECT id FROM lotes WHERE codigo = 'SEC-001')
|
|
AND ol_out.rol = 'output'
|
|
AND ol_in.rol = 'input';
|
|
```
|
|
|
|
### Ver estadísticas de un período
|
|
|
|
```sql
|
|
SELECT
|
|
tipo,
|
|
COUNT(*) as total,
|
|
SUM(cantidad_kg) as kg_totales
|
|
FROM operaciones
|
|
WHERE fecha >= NOW() - INTERVAL '30 days'
|
|
GROUP BY tipo
|
|
ORDER BY total DESC;
|
|
```
|
|
|
|
---
|
|
|
|
## Migraciones Futuras
|
|
|
|
Cuando necesites hacer cambios al esquema en producción:
|
|
|
|
1. **Crear archivo de migración** (ej: `03_add_lugares_table.sql`)
|
|
2. **NO modificar** `01_schema.sql` ni `02_seed.sql` directamente
|
|
3. **Aplicar migración manualmente** en producción
|
|
|
|
Ejemplo de migración:
|
|
|
|
```sql
|
|
-- 03_add_lugares_table.sql
|
|
CREATE TABLE IF NOT EXISTS lugares (
|
|
id SERIAL PRIMARY KEY,
|
|
nombre TEXT NOT NULL,
|
|
tipo TEXT, -- patio, pila, bodega, etc.
|
|
capacidad_kg NUMERIC
|
|
);
|
|
|
|
-- Agregar foreign key a lotes
|
|
ALTER TABLE lotes
|
|
ADD CONSTRAINT fk_lotes_lugar
|
|
FOREIGN KEY (lugar_id) REFERENCES lugares(id);
|
|
```
|
|
|
|
---
|
|
|
|
## Backup y Restore
|
|
|
|
### Hacer backup
|
|
|
|
```bash
|
|
docker exec seguidorDeLotes-postgres pg_dump -U seguidor seguidor_lotes > backup_$(date +%Y%m%d).sql
|
|
```
|
|
|
|
### Restaurar backup
|
|
|
|
```bash
|
|
cat backup_20251121.sql | docker exec -i seguidorDeLotes-postgres psql -U seguidor -d seguidor_lotes
|
|
```
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### "relation lotes does not exist"
|
|
|
|
Los scripts no se ejecutaron. Verificar:
|
|
```bash
|
|
docker logs seguidorDeLotes-postgres
|
|
```
|
|
|
|
Si ves errores, eliminar volumen y reiniciar:
|
|
```bash
|
|
docker-compose down -v
|
|
docker-compose up -d
|
|
```
|
|
|
|
### "permission denied for schema public"
|
|
|
|
Problema de permisos. Conectarse como superuser:
|
|
```bash
|
|
docker exec -it seguidorDeLotes-postgres psql -U postgres -d seguidor_lotes
|
|
|
|
-- Dar permisos
|
|
GRANT ALL ON SCHEMA public TO seguidor;
|
|
GRANT ALL ON ALL TABLES IN SCHEMA public TO seguidor;
|
|
```
|
|
|
|
### Los datos de ejemplo se duplican
|
|
|
|
`02_seed.sql` hace `TRUNCATE` al inicio. Si no quieres perder datos, comenta esa línea.
|
|
|
|
---
|
|
|
|
## Referencias
|
|
|
|
- [PostgreSQL JSON Functions](https://www.postgresql.org/docs/current/functions-json.html)
|
|
- [Recursive Queries (CTE)](https://www.postgresql.org/docs/current/queries-with.html)
|
|
- [Docker Init Scripts](https://hub.docker.com/_/postgres)
|
|
|
|
---
|
|
|
|
**Última actualización**: 2025-11-21
|