Files
excel-import/README.md
T
2026-05-13 12:05:29 +02:00

261 lines
6.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# excel-import
Generisches Kommandozeilen-Tool zum Import von Tabellendateien in Oracle- und PostgreSQL-Datenbanken.
Unterstützte Formate:
| Format | Endung | Paket |
|--------|--------|-------|
| Excel 972003 | `.xls` | `xlrd` |
| Excel 2007+ | `.xlsx`, `.xlsm`, `.xlsb` | `openpyxl` |
| OpenDocument (LibreOffice) | `.ods` | `odfpy` |
## Voraussetzungen
- Python 3.10+
- Für PostgreSQL: `psycopg2-binary`
- Für Oracle: `oracledb` (kein Oracle Client nötig, nutzt den Thin-Modus)
## Installation
```bash
pip install -e .
```
## Schnellstart
```bash
# 1. Struktur der Excel-Datei anzeigen
excel-import inspect meine_datei.xlsx
# 2. Starter-Konfiguration automatisch erzeugen
excel-import generate-config meine_datei.xlsx --dsn "postgresql+psycopg2://user:pass@localhost/mydb"
# 3. Konfiguration anpassen (siehe unten)
# 4. Import ausführen
excel-import run meine_datei.xlsx import_config.yaml
```
---
## Befehle
### `inspect`
Zeigt die Sheets, Spalten und Zeilenzahl einer Excel-Datei — ohne Datenbank-Verbindung.
```bash
excel-import inspect datei.xlsx
```
Beispielausgabe:
```
Sheets in datei.xlsx:
[0] Artikel
Columns (4): Artikelnummer, Bezeichnung, Preis, Interne Notiz
Rows: 1250
[1] Kunden
Columns (3): Kundennummer, Name, E-Mail
Rows: 340
```
---
### `generate-config`
Erzeugt eine YAML-Konfigurationsdatei aus der Struktur der Excel-Datei. Die Datei kann danach manuell angepasst werden.
```bash
excel-import generate-config datei.xlsx \
--dsn "postgresql+psycopg2://user:pass@localhost/mydb" \
--output config.yaml
```
| Option | Standard | Beschreibung |
|--------|----------|--------------|
| `--dsn` | PostgreSQL-Beispiel | SQLAlchemy-DSN der Zieldatenbank |
| `--output` / `-o` | `import_config.yaml` | Ausgabedatei |
---
### `run`
Führt den Import anhand einer YAML-Konfigurationsdatei durch.
```bash
excel-import run datei.xlsx config.yaml
excel-import run datei.xlsx config.yaml --verbose
```
| Option | Beschreibung |
|--------|--------------|
| `-v` / `--verbose` | Ausführliche Ausgabe inkl. SQL-Details |
---
## Konfigurationsdatei
Die YAML-Konfiguration steuert, welche Sheets importiert werden, wie Spalten gemappt werden und welcher Import-Modus verwendet wird.
```yaml
# SQLAlchemy DSN — Beispiele:
# PostgreSQL: postgresql+psycopg2://user:pass@localhost/mydb
# Oracle: oracle+oracledb://user:pass@localhost:1521/?service_name=MYDB
dsn: "postgresql+psycopg2://user:pass@localhost/mydb"
default_varchar_length: 255 # Fallback-Länge für Text-Spalten
sheets:
- sheet: "Artikel" # Sheet-Name oder Index (0, 1, ...)
header_row: 0 # 0-basierter Zeilenindex der Kopfzeile
skip_rows: 0 # Zeilen vor der Kopfzeile überspringen
target_table: "artikel" # Ziel-Tabelle (wird angelegt, falls nicht vorhanden)
mode: "replace" # append | replace | upsert
upsert_keys: [] # Primärschlüssel-Spalten für Upsert
columns:
- source: "Artikelnummer"
target: "artikelnummer"
dtype: "VARCHAR(50)" # optional: Typ-Override
- source: "Bezeichnung"
target: "bezeichnung"
- source: "Preis"
target: "preis"
dtype: "NUMERIC(12,2)"
- source: "Interne Notiz"
target: "interne_notiz"
skip: true # Spalte nicht importieren
```
### Import-Modi
| Modus | Verhalten |
|-------|-----------|
| `append` | Zeilen werden an die bestehende Tabelle angehängt |
| `replace` | Tabelle wird geleert (TRUNCATE), dann neu befüllt |
| `upsert` | Zeilen werden eingefügt oder aktualisiert (anhand `upsert_keys`) |
### Spalten-Konfiguration
| Feld | Pflicht | Beschreibung |
|------|---------|--------------|
| `source` | ja | Spaltenname in der Excel-Datei |
| `target` | ja | Spaltenname in der Datenbank |
| `dtype` | nein | Typ-Override, z.B. `VARCHAR(100)`, `NUMERIC(12,2)`, `DATE` |
| `skip` | nein | Spalte komplett ignorieren (`true`/`false`) |
Unterstützte Typ-Overrides: `VARCHAR(n)`, `TEXT`, `CLOB`, `INTEGER`, `NUMBER`, `NUMERIC(p,s)`, `DECIMAL(p,s)`, `FLOAT`, `DATE`, `DATETIME`, `TIMESTAMP`, `BOOLEAN`.
Ohne `dtype` erkennt das Tool den Typ automatisch aus den Daten.
### Verbindungs-DSN
**PostgreSQL:**
```
postgresql+psycopg2://user:password@host:5432/datenbankname
```
**Oracle (Thin-Modus, kein Client nötig):**
```
oracle+oracledb://user:password@host:1521/?service_name=MYSERVICE
```
```
oracle+oracledb://user:password@host:1521/SID
```
---
## Tabellen-Verwaltung
Existiert die Ziel-Tabelle noch nicht, wird sie automatisch angelegt. Der Spaltentyp wird aus den Daten und der Spalten-Konfiguration abgeleitet.
Enthält `target_table` einen Punkt (z.B. `dl.tabelle1`), wird der Teil vor dem Punkt als Datenbankschema interpretiert. Existiert dieses Schema noch nicht, wird es ebenfalls automatisch angelegt.
Existiert die Tabelle bereits, werden die Daten entsprechend dem gewählten Modus eingefügt — die Tabellenstruktur wird **nicht** geändert. Soll die Struktur angepasst werden, muss die Tabelle vorher manuell geändert oder gelöscht werden.
---
## Beispiele
### Vollständiger Import mit Upsert
```yaml
dsn: "postgresql+psycopg2://user:pass@localhost/mydb"
sheets:
- sheet: "Kunden"
target_table: "kunden"
mode: "upsert"
upsert_keys: ["kundennummer"]
columns:
- source: "Kundennummer"
target: "kundennummer"
dtype: "VARCHAR(20)"
- source: "Name"
target: "name"
- source: "E-Mail"
target: "email"
```
### Sheet per Index ansprechen
```yaml
sheets:
- sheet: 2 # drittes Sheet (0-basiert)
header_row: 1 # Kopfzeile ist in Zeile 2 (0-basiert: 1)
skip_rows: 0
target_table: "rohdaten"
mode: "append"
columns: [] # alle Spalten importieren, keine Umbenennung
```
### Mehrere Sheets in einem Lauf
```yaml
dsn: "oracle+oracledb://scott:tiger@localhost:1521/?service_name=ORCL"
sheets:
- sheet: "Artikel"
target_table: "artikel"
mode: "replace"
columns:
- source: "ArtNr"
target: "art_nr"
dtype: "VARCHAR(50)"
- source: "Preis"
target: "preis"
dtype: "NUMERIC(12,2)"
- sheet: "Lager"
target_table: "lagerbestand"
mode: "replace"
columns: []
```
---
## Projektstruktur
```
excel-import/
├── pyproject.toml
├── examples/
│ └── import_config.yaml
├── excel_import/
│ ├── config.py # Konfigurationsklassen + YAML-Loader
│ ├── reader.py # Excel-Einlesen (.xls + .xlsx)
│ ├── schema.py # Automatische Typ-Erkennung + DDL
│ ├── importer.py # Import-Logik (append/replace/upsert)
│ └── cli.py # Kommandozeilen-Interface
└── tests/
├── test_config.py
├── test_reader.py
└── test_importer.py
```
## Tests ausführen
```bash
pip install -e ".[dev]"
pytest
```