This project loads ecommerce CSV datasets into PostgreSQL using a repeatable pipeline.
- Dockerized PostgreSQL for consistent local setup
- SQL-based schema creation with constraints and indexes
- Idempotent data loading (safe to re-run)
- Validation checks for row counts and foreign keys
- CI pipeline with GitHub Actions for automated load tests
data/raw/*.csv: source datasets (products,customers,orders,orderitems)sql/01_schema.sql: creates tables and indexessql/02_load_data.sql: truncates and reloads data from CSVsql/03_validate.sql: verifies row counts and referential integrityscripts/run_pipeline.sh: one-command local pipeline runnerdocker-compose.yml: local PostgreSQL service.github/workflows/load-data-pipeline.yml: CI pipeline
erDiagram
PRODUCTS {
INT product_id PK
TEXT name
NUMERIC price
TEXT category
}
CUSTOMERS {
INT customer_id PK
TEXT name
TEXT email UK
}
ORDERS {
INT order_id PK
INT customer_id FK
TIMESTAMP order_date
}
ORDER_ITEMS {
INT order_item_id PK
INT order_id FK
INT product_id FK
INT quantity
}
CUSTOMERS ||--o{ ORDERS : places
ORDERS ||--o{ ORDER_ITEMS : contains
PRODUCTS ||--o{ ORDER_ITEMS : includes
- Docker Desktop (running)
- Bash shell (macOS already has it)
- Create environment file:
Development:
make setup-dev
Production-like profile:
make setup-prod
-
Open
.env.devor.env.productionand set a strong password forPOSTGRES_PASSWORD. -
Run full pipeline:
Development:
make pipeline-dev
Production-like profile:
make pipeline-prod
You should see final output: [DONE] Pipeline completed successfully.
- Start database only:
make up ENV=.env.dev - Run full load + validation:
make pipeline-dev - Stream DB logs:
make logs ENV=.env.dev - Stop database:
make down ENV=.env.dev
Dev profile note: .env.dev uses host port 55432 to avoid collisions with a local PostgreSQL service.
Production-like profile note: .env.production uses host port 55433 to avoid collisions with other local services.
- Full local guide:
docs/local-run.md - Query solutions (markdown):
docs/solutions.md - Query solutions (runnable SQL):
docs/solutions.sql
- Pipeline is idempotent: every run recreates table contents in a clean order.
- Constraints and foreign keys prevent bad data from loading silently.
- Validation query checks for orphans after every load.
- CI workflow ensures schema/load/validation works on every PR or push.
Set these repository secrets before running the GitHub Actions pipeline:
CI_POSTGRES_DBCI_POSTGRES_USERCI_POSTGRES_PASSWORD
Recommended values:
CI_POSTGRES_DB=bongadbCI_POSTGRES_USER=bonga_adminCI_POSTGRES_PASSWORD=<strong_password>
- Files in
data/raw/are synthetic demo datasets and are safe to keep in GitHub. - Never commit real customer data, sensitive business data, secrets, or PII.
- Put private datasets in
data/private/(ignored by git) or in secure cloud storage. - Keep repository datasets small and focused on reproducible testing/training use cases.
-
Error: password authentication failed
- Check
.envvalues and rerunmake down && make up && make load
- Check
-
Error: CSV file not found
- Ensure CSV files exist under
data/raw/
- Ensure CSV files exist under
-
Port 5432 already in use
- Change
POSTGRES_PORTin.envto another port (for example 5433)
- Change