2010-02-11 8 views
10

Ich bin eine kleine DB-Testsuite zu schreiben, die Konfigurationsdateien mit Abfragen liest und die erwarteten Ergebnisse, z.B .:Python: Lesen Konfigurationsdatei mit mehreren Zeilen pro Taste

query   = "SELECT * from cities WHERE name='Unknown';" 
count   = 0 
level   = 1 
name   = "Check for cities whose name should be null" 
suggested_fix = "UPDATE cities SET name=NULL WHERE name='Unknown';" 

Das funktioniert gut; Ich teile jede Zeile mit Pythons string.partition('=').

Mein Problem ist sehr lange SQL-Abfragen. Momentan füge ich diese Abfragen einfach als One-Liner ein, was hässlich und nicht zu pflegen ist.

Ich möchte eine elegante, pythonische Art finden, das Recht eines Ausdrucks zu lesen, auch wenn es sich über viele Zeilen erstreckt.

Hinweise:

  • meine SQL-Abfragen die =
  • enthalten könnte ich gar keine Lust " s um die rechte Seite zu zwingen, weil es ohne es viele vorhandene Dateien.

EDIT:

ConfigParser ist groß, aber es zwingt mich, einen Raum oder eine Registerkarte am Anfang jeder Zeile in einem mehrzeiligen Eintrag hinzuzufügen. Dies könnte ein großer Schmerz sein.

Vielen Dank im Voraus,

Adam

+0

dieser Raum/Tab nicht im endgültigen Wert enthalten – SilentGhost

+0

Können Sie das näher erläutern? Ich habe deinen Kommentar nicht verstanden. –

Antwort

9

Dies ist fast genau der Anwendungsfall, den uns zu YAML wechseln gemacht (Wikipedia, python implementation, documentation; Sie vielleicht bei JSON als Alternative zu sehen).YAML hat einige Vorteile gegenüber configparser oder json:

  • menschliche Lesbarkeit (besser als JSON für größere Dateien);
  • kann beliebige Python-Objekte serialisieren (was es so un-sicher wie pickle macht, aber es gibt eine safe_load Funktion in der Python-Implementierung, um dieses Problem zu beheben). Dies ist bereits nützlich für etwas so einfaches wie ein datetime Objekt.

Der Vollständigkeit halber sind die Hauptnachteile (IMO):

  • Python Umsetzung durch eine Größenordnung langsamer ist als JSON Umsetzung;
  • weniger portabel über Plattformen als JSON.

Zum Beispiel

import yaml 

sql = """ 
query   : "SELECT * from cities 
WHERE name='Unknown';" 
count   : 0 
level   : 1 
name   : "Check for cities whose name should be null" 
suggested_fix : "UPDATE cities SET name=NULL WHERE name='Unknown';" 
""" 

sql_dict = yaml.safe_load(sql) 

print(sql_dict['query']) 

druckt

SELECT * from cities WHERE name='Unknown'; 
+0

+1: Yaml ist ideal für eine solche Konfiguration – van

+0

+1 Tolle Idee. Will hineinschauen. –

+0

+1 passt wunderbar zum Anwendungsfall. –

12

Die Python-Standardbibliothek Modul ConfigParser unterstützt dies standardmäßig. Die Konfigurationsdatei hat in einem Standardformat sein:

[Long Section] 
short: this is a normal line 
long: this value continues 
in the next line 

Die Konfigurationsdatei oben mit dem folgenden Code gelesen werden kann:

import ConfigParser 
config = ConfigParser.ConfigParser() 
config.read('longsections.cfg') 
long = config.get('Long Section', 'long') 
+1

Ich habe ein Problem mit dieser Lösung, da beim Parsen der Datei Fehler auftreten. Gemäß der Dokumentation wird für mehrzeilige Werte ein Einzug benötigt. Ich habe 4 Leerzeichen am Anfang von "in der nächsten Zeile" hinzugefügt und es funktioniert. – MikeCPT

1

Ich würden Sie einen regulären Ausdruck verwenden vorschlagen ... Die Code könnte so aussehen, um Sie starten sind:

import re 

test="""query = "select * from cities;" 
count = 0 
multine_query = "select * 
from cities 
    where name='unknown';" 
""" 

re_config = re.compile(r'^(\w+)\s*=\s*((?:".[^"]*")|(?:\d+))$', re.M) 
for key, value in re_config.findall(test): 
    if value.startswith('"'): 
     value = value[1:-1] 
    else: 
     value = int(value) 
    print key, '=', repr(value) 

Die Ausgabe dieses Beispiels ist:

~> python test.py 
query = 'select * from cities;' 
count = 0 
multine_query = "select *\nfrom cities\n  where name='unknown';" 

Hoffe, dass hilft!

Grüße, Christoph

+1

+1 Das sollte funktionieren, aber ich bevorzuge ein vorgefertigtes Paket, das alle Arten von Randbedingungen unterstützt. –

Verwandte Themen