Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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. 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
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