PHPackages                             jrmgx/etl-package - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. jrmgx/etl-package

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

jrmgx/etl-package
=================

ETL: Extract, Transform, Load

v1.2.1(3y ago)115[3 PRs](https://github.com/jrmgx/etl-package/pulls)MITPHPPHP ^8.1

Since Feb 26Pushed 1y ago1 watchersCompare

[ Source](https://github.com/jrmgx/etl-package)[ Packagist](https://packagist.org/packages/jrmgx/etl-package)[ Docs](https://github.com/jrmgx/ETL-package)[ RSS](/packages/jrmgx-etl-package/feed)WikiDiscussions main Synced today

READMEChangelog (4)Dependencies (12)Versions (8)Used By (0)

ETL Package
===========

[](#etl-package)

**THIS IS A WORK IN PROGRESS**

[ETL: Extract, Transform, Load](https://en.wikipedia.org/wiki/Extract,_transform,_load)

This package will allow you to:

- **Extract** data from a given source
- **Transform** it as you need
- **Load** the result to a given destination

It is based on a simple config file described below.

Basic Example
-------------

[](#basic-example)

In this basic example:

- We are getting a CSV file from the local repository
- We transform the data a bit
- We send back the transformed data into an API as JSON

Yaml is optional, it could have been a plain PHP array.

```
extract:
  pull:
    type: file
    uri: ./demo/data_in.csv
  read:
    format: csv
    options:
      trim: true

transform:
  filter:
    type: query
    options:
      where: 'Age > :min'
      parameters:
        min: 30
  mapping:
    type: expressive
    map:
      out.name: in.Name
      out.sex: in.Sex
      out.age_in_sec: 'in.Age * 365 * 24 * 60 * 60'

load:
  write:
    format: json
  push:
    type: http
    uri: https://webhook.site/f24c112b-8344-4fe3-a9e5-53baf36c912f
    options:
      headers:
        'Authorization': 'Basic 9e222b3b7647c7'
```

Configuration
-------------

[](#configuration)

On the ETL part, everything is configured into one single file that describe each steps.
But for the sake of readability, the documentation has been split, so each component has it own page.

### Extractors

[](#extractors)

Extractors are responsible to pull and read your data.

**Pull**: Responsible for pulling the data from its source, be it a local file, an API or a database.
**Read**: Given the resource gotten in Pull, read that and convert it to a normalized array to work with later.

Most of the time, the *Pull* and *Read* section are independent, but for some type of resource (like database), they work together (pull will make and handle the connection and read get the data from that connection).

- [Extract Pull: File](documentation/extract_pull_file.md)
- [Extract Pull: Http](documentation/extract_pull_http.md)
- [Extract Read: Csv](documentation/extract_read_csv.md)
- [Extract Read: Json](documentation/extract_read_json.md)
- [Extract: Database](documentation/extract_database.md)

### Transformers

[](#transformers)

Transformers are responsible to filter and transform the given data.

**Filter**: Given the data, apply specific filtering logic.
**Mapping**: Given the data, associate output fields to input fields, with optional transformation.

- [Transform Mapping: Expressive](documentation/transform_mapping_expressive.md)
- [Transform Mapping: Simple](documentation/transform_mapping_simple.md)
- [Transform Filter: Query](documentation/transform_filter_query.md)

#### Chaining

[](#chaining)

Sometimes you may want to take advantage of multiple transformers, you can do it by adding multiples entries into a `transformers` section.

```
transformers:
  first_transform: # This name does not matter, but it has to be unique
    mapping:
      type: simple
      map:
        out.name: in.Name
        out.sex: in.Sex
        out.size: in.Height

  second_transform: # This name does not matter, but it has to be unique
    filter:
      type: query
      options:
        where: 'size > :size'
        parameters:
          size: 2
    mapping:
      type: expressive
      map:
        out.name: in.name
        out.sex: in.sex
        out.squared: 'in.size * in.size'
```

### Loaders

[](#loaders)

Loaders are responsible to write and push your data.

**Write**: Given the data, write and convert it to the specified format / type.
**Push**: Given the resource gotten in Write, push it to the configured source.

Most of the time, the *Write* and *Push* section are independent, but for some type of resource (like database), they work together (write prepare the data and push will handle the connection).

- [Load Write: Twig](documentation/load_write_twig.md)
- [Load Write: Json](documentation/load_write_json.md)
- [Load: Database](documentation/load_database.md)
- [Load Push: Http](documentation/load_push_http.md)
- [Load Push: File](documentation/load_push_file.md)

Use it in your project
----------------------

[](#use-it-in-your-project)

### Symfony or via dependency injection

[](#symfony-or-via-dependency-injection)

In a Symfony project you can add those lines to your `services.yaml` to make it work:

```
    Jrmgx\Etl\:
        resource: '../vendor/jrmgx/etl-package/src/'
        exclude:
            - '../vendor/jrmgx/etl-package/src/Config/'
```

This will register everything as a service, and then you can inject `Etl` like this:

```
class YourService
{
    public function __construct(private readonly Etl $etl) { }

    public function yourMethod(): void
    {
        // Yaml is optional, you can provide an array instead
        $configFile = Yaml::parseFile(__DIR__.'/../../config/etl.yaml');
        $config = new Config($configFile, __DIR__ . '/../../');

        $this->etl->execute($config);
    }
}
```

In other projects using dependency injection it should be pretty similar.

### Manual setup

[](#manual-setup)

TODO

Add custom Extractors/Transformers/Loaders
------------------------------------------

[](#add-custom-extractorstransformersloaders)

### Implement Custom Extractors

[](#implement-custom-extractors)

...

### Implement Custom Transformers

[](#implement-custom-transformers)

...

### Implement Custom Loaders

[](#implement-custom-loaders)

...

Development Environment
=======================

[](#development-environment)

Install the project
-------------------

[](#install-the-project)

...

Run the project
---------------

[](#run-the-project)

...

Tests and code style
--------------------

[](#tests-and-code-style)

...

Licence
-------

[](#licence)

MIT

Attributions
------------

[](#attributions)

`data_in.csv` comes from:

###  Health Score

28

—

LowBetter than 52% of packages

Maintenance29

Infrequent updates — may be unmaintained

Popularity7

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~1 days

Total

4

Last Release

1217d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/5556f480403bebb5e759f156ecc1aa7296ed0082944bfbd591e3637985ec36ca?d=identicon)[jrmgx](/maintainers/jrmgx)

---

Top Contributors

[![jrmgx](https://avatars.githubusercontent.com/u/42989?v=4)](https://github.com/jrmgx "jrmgx (14 commits)")

---

Tags

extracttransformetlload

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/jrmgx-etl-package/health.svg)

```
[![Health](https://phpackages.com/badges/jrmgx-etl-package/health.svg)](https://phpackages.com/packages/jrmgx-etl-package)
```

###  Alternatives

[easycorp/easyadmin-bundle

Admin generator for Symfony applications

4.3k17.9M388](/packages/easycorp-easyadmin-bundle)[chameleon-system/chameleon-base

The Chameleon System core.

1028.6k5](/packages/chameleon-system-chameleon-base)[sulu/sulu

Core framework that implements the functionality of the Sulu content management system

1.3k1.4M203](/packages/sulu-sulu)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

585.6M568](/packages/shopware-core)[contao/core-bundle

Contao Open Source CMS

1231.6M2.8k](/packages/contao-core-bundle)[open-dxp/opendxp

Content &amp; Product Management Framework (CMS/PIM)

9421.6k61](/packages/open-dxp-opendxp)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
