datapipeline 2.0.0: Gem aus dem Projekt etl herausgelöst

This commit is contained in:
wkh
2026-10-08 15:30:02 +02:00
commit cce7b03ca9
56 changed files with 5205 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
#
# Kundenliste aus CSV prüfen, mit Ländern anreichern, nach SQLite und Excel schreiben
#
# bin/etl run examples/kunden_import.rb [--out=tmp] [--dry-run]
#
require 'fileutils'
require 'datapipeline'
DATA = File.expand_path('data', __dir__)
out = DataPipeline.params.fetch(:out, 'tmp')
FileUtils.mkdir_p(out)
DataPipeline.new do
version 'kunden_import 1.0'
# Nachschlagetabelle, einmal geladen: { 'DE' => { 'code' => 'DE', 'name' => 'Deutschland', 'eu' => true }, ... }
laender = lookup container(:json, file: "#{DATA}/laender.json"), key: 'code', unique: true
read container(:csv, file: "#{DATA}/kunden.csv", csv: { col_sep: ';' })
# fehlerhafte Zeilen mit Grund in eine eigene Datei, der Lauf geht weiter
on_error :collect, to: container(:csv, file: "#{out}/kunden_fehler.csv")
# 1. prüfen
validate 'kundennr' => { required: true, format: /\A\d{6}\z/ },
'name' => { required: true, max: 40 },
'umsatz' => { type: :decimal }
validate { |row| "Land #{row['land']} unbekannt" unless laender.key?(row['land']) }
# 2. nur aktive Kunden
filter { |row| row['status'] == 'aktiv' }
# 3. anreichern und umbauen
map do |row|
land = laender.fetch(row['land'])
{
'kundennr' => row['kundennr'],
'name' => row['name'].strip,
'land' => land['name'],
'eu' => land['eu'] ? 'ja' : 'nein',
'umsatz' => row['umsatz'].to_f.round(2)
}
end
# 4. schreiben: alle Kunden nach SQLite, EU-Kunden zusätzlich als Excel-Liste
write container(:sqlite, database: "#{out}/kunden.sqlite3", table: 'kunden', create: true, truncate: true)
write container(:excel, file: "#{out}/eu_kunden.xlsx", sheet: 'EU-Kunden'), only: ->(row) { row['eu'] == 'ja' }
on_finish { |stats| puts "kunden_import: #{stats}" }
end.run