Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.6 KiB
excel-import
Generisches Kommandozeilen-Tool zum Import von Tabellendateien in Oracle- und PostgreSQL-Datenbanken.
Unterstützte Formate:
| Format | Endung | Paket |
|---|---|---|
| Excel 97–2003 | .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
pip install -e .
Schnellstart
# 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.
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.
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.
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.
# 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
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
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
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
pip install -e ".[dev]"
pytest