> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Jobs de extracción

> Cómo un job de extracción de Fetcher describe datasources, tablas, schemas y campos — y qué pasa con el job desde su creación hasta el resultado almacenado.

Un job de extracción es una solicitud asíncrona para leer datos de una o varias bases de datos registradas. El Manager acepta el job y lo encola. Un Worker ejecuta la extracción y almacena el resultado. Esta página explica la solicitud que envías y el camino que recorre el job.

## La solicitud

***

Un job lleva dos partes: `dataRequest` y `metadata`.

```json theme={null}
{
  "dataRequest": {
    "mappedFields": {
      "my_postgres": {
        "public.accounts": ["id", "email", "created_at"],
        "accounting.invoices": ["*"]
      },
      "my_mongo": {
        "transactions": ["*"]
      }
    }
  },
  "metadata": {
    "source": "payments",
    "correlationId": "settlement-2026-07-13"
  }
}
```

`mappedFields` es el corazón de la solicitud. Mapea el nombre de configuración de cada datasource a las tablas que quieres, y cada tabla a los campos que quieres.

`metadata.source` es **obligatorio**. Nombra el producto dueño del job. El Manager rechaza una solicitud que no lo trae. El Manager también rechaza la solicitud cuando una conexión referenciada pertenece a otro producto, o no pertenece a ningún producto. Los datasources internos no llevan producto, así que esta comprobación no aplica a ellos.

## Proyección de campos

***

Nombra los campos que quieres, o pide todos:

* Una lista de nombres de campos extrae exactamente esos campos.
* La entrada única `["*"]` extrae todas las columnas de la tabla. El comodín debe ser la única entrada de la lista.

Fetcher valida cada campo nombrado contra el esquema descubierto antes de consultar. Un nombre de campo desconocido hace fallar el job y nombra los campos causantes en el error. Una tabla sin ningún campo válido también hace fallar el job.

## Varios datasources, tablas y schemas

***

Un mismo job puede leer de varios datasources a la vez. Cada datasource puede aportar varias tablas. Cada tabla puede estar en un schema distinto.

Escribe el nombre de una tabla en una de dos formas:

* **Sin calificar** — `accounts`. Fetcher la lee del schema por defecto del motor: `public` en PostgreSQL, `dbo` en SQL Server.
* **Calificada con schema** — `accounting.invoices`. El prefijo antes del punto es el schema. En Oracle es el owner.

Fetcher reúne los prefijos de schema distintos que hay en `mappedFields` y descubre solo esos namespaces. Si algún nombre de tabla va sin calificar, el descubrimiento añade además el schema por defecto del motor: `public` en PostgreSQL, `dbo` en SQL Server.

Dos motores no aceptan una lista de schemas. MySQL trata la base de datos conectada como el namespace. MongoDB tiene colecciones en lugar de schemas, así que el nombre de una colección siempre va sin calificar.

## Límites

***

El motor de extracción acota cada job. Estos son los valores por defecto:

| Límite                            | Valor por defecto |
| --------------------------------- | ----------------- |
| Datasources por job               | 10                |
| Tablas por datasource             | 20                |
| Campos por tabla                  | 50                |
| Datasources extraídos en paralelo | 4                 |
| Tiempo máximo de extracción       | 5 minutos         |
| Tamaño del resultado serializado  | 256 MiB           |

El Manager rechaza un job con más de 10 datasources antes de que llegue a la cola. Un resultado que supera el límite de tamaño hace fallar el job. Fetcher nunca devuelve ni almacena un resultado truncado. `ENGINE_MAX_RESULT_BYTES` baja el techo de tamaño en el Worker. Una solicitud puede bajar un límite, pero nunca puede subirlo por encima del valor por defecto del motor.

## Jobs duplicados

***

El Manager calcula un hash SHA-256 sobre la solicitud completa — `dataRequest` y `metadata` juntos. Luego busca un job con el mismo hash creado en los últimos **5 minutos**.

* Una coincidencia devuelve el job existente con HTTP 200. No corre una segunda extracción.
* Sin coincidencia, crea un job nuevo y devuelve HTTP 202.
* Una coincidencia que ya **falló** no bloquea un reintento. El Manager crea un job nuevo.

Los metadatos forman parte del hash. Dos solicitudes que leen los mismos datos bajo IDs de correlación distintos son jobs distintos.

## Ciclo de vida del job

***

| Estado       | Significado                                                 |
| ------------ | ----------------------------------------------------------- |
| `pending`    | El Manager aceptó el job y lo publicó en la cola.           |
| `processing` | Un Worker tomó el job y lee los datasources.                |
| `completed`  | El resultado está almacenado, y se publica `job.completed`. |
| `failed`     | La extracción se detuvo, y se publica `job.failed`.         |

Antes de crear el job, el Manager resuelve cada nombre de datasource a una conexión y abre una conexión real con cada una. Un datasource que falla esta prueba rechaza toda la solicitud. Los datasources internos configurados por variables de entorno no pasan por la prueba.

Un Worker toma un job solo mientras el job sigue en `pending`. Luego lo mueve a `processing` y arranca la extracción. Los datasources corren en paralelo hasta el límite de concurrencia. La ejecución es fail-fast: el primer datasource que falla termina el job, y Fetcher no almacena ningún resultado parcial.

Si todo sale bien, el Worker escribe el resultado en el object storage y registra dos valores en el job: la ruta del resultado y la firma HMAC del resultado. Después publica el evento terminal.

## Próximos pasos

***

<CardGroup cols={2}>
  <Card title="Filtros" icon="filter" href="/es/fetcher/fetcher-filters">
    Los diez operadores de filtro y la forma de valor que toma cada uno.
  </Card>

  <Card title="Fuentes de datos" icon="database" href="/es/fetcher/fetcher-datasources">
    Qué se comporta distinto en cada uno de los cinco motores de base de datos.
  </Card>
</CardGroup>
