Liste, Dictionary oder Kombination - was hierfür richtig?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
SchaubFD
User
Beiträge: 9
Registriert: Montag 30. Juni 2008, 13:33

Liste, Dictionary oder Kombination - was hierfür richtig?

Beitragvon SchaubFD » Donnerstag 3. Juli 2008, 19:59

Hallo,

ich habe öfters folgendes Problem. Ich muss Daten aus verschiedenen Quellen (Dateien) verbinden, möchte aber auf Datenbanken verzichten, da die Datenmengen unproblematisch für Skriptsprachen sind. Teilweise sind es zusammengesetzte Schlüsselwerte wie z.B. im folgenden Beispiel Kostenträger und Kostenstelle. Bisher habe ich dies über einen String mit festen Längen gemacht z.B. '0013_4700'' als Key. Wie würdet ihr solche Probleme angehen. Ich möchte den Code kompakt und trotzdem sehr lesbar halten.

Folgendes Beispiel ist einfach mal so zusammengesetzt und kann durchaus Fehler enthalten! Es soll auch als Beispiel für andere Forenteilnehmer dienen, die ähnliches machen.

Code: Alles auswählen

# -*- coding: utf-8 -*-
# Quellcode im Unicode Zeichensatz

# Telefonliste Vorname, Nachname, Telefon
telefon=[]
telefon.append(['Ingo','Meier','132'])
telefon.append(['Paul','Schmitt','342'])
telefon.append(['Ute','Meier'],'105')
telefon.append(['Peter','Schmidt','311'])

# Abteilung Abteilung, Kostenstelle, Kostenträger
abteilung=[]
abteilung.append('2','4800','11')
abteilung.append('1','4700','13')

# Zuordnung Abteilung, Teiefon
zuordnung=[]
zuordnung.append('1'.'311')
zuordnung.append('1'.'342')
zuordnung.append('2'.'132')
zuordnung.append('2'.'105')

# Gesprächskosten
kosten=[]
kosten.append('105','34,50']
kosten.append('132','12,34']
kosten.append('311','15,67']
kosten.append('342','10,10']

# Ziel der Auswertung
# Eine Liste sortiert nach Abteilung, Kostenträger, Kostenstelle
# mit Auflistung der Telefonnutzer je Abteilung sortiert
# nach Nachname, Vorname. Es werden alle Felder in der
# Ausgabe ausgegeben. Die Daten sollen später in eine CSV Datei.

Ausgabe:
-----------------------------------------------------------
'1','13','4700','Schmidt','Peter','311','15,67'
'1','13','4700','Schmitt','Paul' ,'342','10,10'
'2','11','4800','Meier'  ,'Ingo' ,'132','12,34'
'2','11','4800','Meier'  ,'Ute'  ,'105','34,50'
EyDu
User
Beiträge: 4866
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Beitragvon EyDu » Donnerstag 3. Juli 2008, 20:05

Wenn du keine Datenbank installieren willst, dann nimm doch SQLite. Das ist viel flexibler und weniger fehleranfällig als eine eigene Lösung.
DasIch
User
Beiträge: 2405
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Donnerstag 3. Juli 2008, 20:07

Dictionaries?
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Beitragvon CM » Donnerstag 3. Juli 2008, 20:31

Das richt geradezu nach dicts. Das [mod]shelve[/mod]-modul könnte auch was für Dich sein.
BlackJack

Beitragvon BlackJack » Donnerstag 3. Juli 2008, 20:58

Ich würde hier auch `sqlite` empfehlen. Wenn Dictionaries mit zusammengesetzten Schlüsseln, dann würde ich aber Tupel als Schlüssel nehmen und nicht mit Zeichenketten operieren. Überhaupt sollte man die Zahlen, die als Zahlen behandelt werden sollen auch als solche verarbeiten. Sonst bekommt man beim Sortieren schnell Probleme wenn "Zeichenkettenzahlen" alphabetisch und nicht nach ihrem numerischen Wert sortiert werden.
SchaubFD
User
Beiträge: 9
Registriert: Montag 30. Juni 2008, 13:33

Beitragvon SchaubFD » Donnerstag 3. Juli 2008, 22:05

Kurze Zwischenfrage, wo finde ich eine Kurzübersicht/Dokumentation zu SQLight am besten mit Python Beispielen?

Ich möchte halt nicht Oracle, SQL-Server oder Access einsetzen, da man sich dann immer fest an etwas bindet oder Treiber/ODBC dazu notwendig wären. Natürlich wären geschachtelte SQL Abfragen dabei sinnvoller. Es soll möglichst übersichtlich bleiben.

Wenn dieses SQLight gut sein sollte, dann könnte ich mir den Aufwand selbst gestrickter Strukturen sparen.
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Beitragvon Karl » Donnerstag 3. Juli 2008, 22:12

SchaubFD hat geschrieben:Kurze Zwischenfrage, wo finde ich eine Kurzübersicht/Dokumentation zu SQLight am besten mit Python Beispielen?

Ich möchte halt nicht Oracle, SQL-Server oder Access einsetzen, da man sich dann immer fest an etwas bindet oder Treiber/ODBC dazu notwendig wären. Natürlich wären geschachtelte SQL Abfragen dabei sinnvoller. Es soll möglichst übersichtlich bleiben.

Wenn dieses SQLight gut sein sollte, dann könnte ich mir den Aufwand selbst gestrickter Strukturen sparen.

Ich hab's zwar noch nicht eingesetzt aber erstens mal heißt es SQLite, nicht light ;)
2. Die Syntax ist wohl einfach die normale SQL-Syntax wie zum Beispiel bei MySQL auch, ansonsten schau mal hier:
http://www.sqlite.org/lang.html
Wo du Pythonbeispiele findest, weiß ich nicht aber Google hat da bestimmt was ;)
DasIch
User
Beiträge: 2405
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Beitragvon DasIch » Donnerstag 3. Juli 2008, 22:20

Ich würde in diesem Falle wohl Elixir o.ä. einsetzen.
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

Beitragvon lutz.horn » Freitag 4. Juli 2008, 08:59

SchaubFD hat geschrieben:Kurze Zwischenfrage, wo finde ich eine Kurzübersicht/Dokumentation zu SQLight am besten mit Python Beispielen?


Ich habe Dein Problem mal kurz mit SQLite implementiert. Zuerst musst Du die Struktur der Datenbank anlegen. Die DDL-Statemenst könnten z. B. so aussehen (Datei telefon-ddl.sql):

Code: Alles auswählen

create table telefon (telefonnummer integer not null primary key,
                      vorname string not null,
                      nachname string not null);

create table abteilung (id integer primary key,
                        kostenstelle integer not null,
                        kostentraeger integer not null);

create table abteilung_telefon (abteilung_id integer not null,
                                telefon_id integer not null);

create table kosten (telefon_id integer not null,
                     kosten double);


Um mit dem sqlite-Binary die Datenbank zu erzeugen, reicht

[code=]$ sqlite3 telefon.sqlite3 < telefon-ddl.sql[/code]

Dann erzeugt dieser Python-Code die gewünschte CSV-Datei.

Code: Alles auswählen

# -*- coding:utf8 -*-

import sqlite3
import csv

connection = sqlite3.connect("telefon.sqlite3")

insert_sql = "insert into telefon values (? ,?, ?)"
connection.executemany(insert_sql, [(132, "Ingo", "Meier"),
                                    (342, "Paul", "Schmitt"),
                                    (105, "Ute", "Meier"),
                                    (311, "Peter", "Schmidt")])

insert_sql = "insert into abteilung values (?, ?, ?)"
connection.executemany(insert_sql, [(2, 4800, 11),
                                    (1, 4700, 13)])

insert_sql = "insert into abteilung_telefon values (?, ?)"
connection.executemany(insert_sql, [(1, 311),
                                    (1, 342),
                                    (2, 132),
                                    (2, 105)])

insert_sql = "insert into kosten values (?, ?)"
connection.executemany(insert_sql, [(105, 34.50),
                                    (132, 12.34),
                                    (311, 15.67),
                                    (342, 10.10)])

connection.commit()

cursor = connection.execute("""
select abteilung.id, abteilung.kostentraeger, abteilung.kostenstelle,
       telefon.nachname, telefon.vorname, telefon.telefonnummer,
       kosten.kosten
from abteilung, abteilung_telefon, telefon, kosten
where abteilung.id = abteilung_telefon.abteilung_id
  and telefon.telefonnummer = abteilung_telefon.telefon_id
  and kosten.telefon_id = telefon.telefonnummer
order by abteilung.id, telefon.nachname, telefon.vorname;""")

writer = csv.writer(open("telefon.csv", "w"))
writer.writerow(["Abteilung", "Kostenträger", "Kostenstelle", "Nachname",
                "Vorname", "Telefon", "Kosten"])
writer.writerows(cursor.fetchall())


Ergebnis is telefon.csv:

Code: Alles auswählen

Abteilung,Kostenträger,Kostenstelle,Nachname,Vorname,Telefon,Kosten
1,13,4700,Schmidt,Peter,311,15.67
1,13,4700,Schmitt,Paul,342,10.1
2,11,4800,Meier,Ingo,132,12.34
2,11,4800,Meier,Ute,105,34.5
https://www.xing.com/go/invite/18513630.6a91d4
SchaubFD
User
Beiträge: 9
Registriert: Montag 30. Juni 2008, 13:33

Beitragvon SchaubFD » Freitag 4. Juli 2008, 09:59

Hallo Lutz,

DANKE!

... deine Antwort macht mich fast sprachlos! Ich bin gleich aus zwei Gründen sehr erfreut darüber. Zu einem Teil, ich habe nicht mit einer kompletten Lösung gerechnet. Zum anderen Teil, deine Antwort beantwortet mir eine Frage, die ich noch stellen wollte (massiges aufrufen von SQL Befehlen bremst). Zudem ist es auch ein schönes Beispiel für sqlite (jetzt richtig geschrieben)

Ich hoffe in naher Zukunft auch mal so gut helfen zu können.
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

Beitragvon lutz.horn » Freitag 4. Juli 2008, 10:13

SchaubFD hat geschrieben:Zu einem Teil, ich habe nicht mit einer kompletten Lösung gerechnet. Zum anderen Teil, deine Antwort beantwortet mir eine Frage, die ich noch stellen wollte (massiges aufrufen von SQL Befehlen bremst).


Gern geschehen.

Was ich nicht berücksichtigt habe, ist z. B. referentielle Integrität über Fremdschlüssel. Dazu gibt es zwar eine SQL-Syntax, die aber von SQLite ignoriert wird. Es ist deswegen möglich, in die von mir beschriebenen Tabellen z. B. Kosten einzutragen, die auf eine nicht existierende Telefonnummer verweisen.

Das Schöne an SQL mit Python ist, dass die beteiligten Konzpete und Klassen in der Python Database API Specification v2.0 datenbankunabhängig spezifiziert werden. Du kannst also zumindest den Python-Code auch mit einer MySQl-Datenbank verwenden, für die allerdings die DDL-Statements anzupasen wären.
https://www.xing.com/go/invite/18513630.6a91d4

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]