Add README with usage documentation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,250 @@
|
|||||||
|
# excel-import
|
||||||
|
|
||||||
|
Generisches Kommandozeilen-Tool zum Import von Excel-Dateien (`.xls` und `.xlsx`) in Oracle- und PostgreSQL-Datenbanken.
|
||||||
|
|
||||||
|
## 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. Das Schema wird aus den Daten und der Spalten-Konfiguration abgeleitet.
|
||||||
|
|
||||||
|
Existiert die Tabelle bereits, werden die Daten entsprechend dem gewählten Modus eingefügt — die Tabellenstruktur wird **nicht** geändert. Soll das Schema 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
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user