Files
excel-import/README.md
T
2026-05-13 11:33:44 +02:00

6.4 KiB

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

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