Hallo
Ich habe Daten in einer DBF Datenbank, die ich mittels dbfpy auslese und in eine SQLite3 Datenbank einlesen möchte (zwecks besserer Nachverarbeitung mittels SQL). Das Problem ist nur, daß nicht immer in jedem Feld der Ursprungstabelle ein Wert steht, deshalb erscheint auch die folgende Fehlermeldung::(
sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 19, and there are 0 supplied.
In Wirklichkeit sind es 31 Spalten aber ich habe es auf 19 reduziert, aber auch dort kommt es vor, daß es leere Spalten in der Ursprungstabelle gibt. Leider ist schon der erste Eintrag nicht vollständig, somit wird nichts in die SQLite Datenbank geschrieben.
Ich habe mir schon überlegt, ob man bei jeder Spalte vorher schaut, ob was drin steht und sie dann überspringt, aber das scheint mir zu aufwendig...
Beispielcode kann ich bei Bedarf schicken, aber es scheint sich hier ja um ein generelles Datenbankproblem im Umgang mit leeren Feldern zu handeln.
Weiß jemand, wie man so ein Problem einfach umgehen kann?
Ach ja: Ich benutze Python 2.5 unter WinXP.
Gruß Hans
Leere Felder in SQLite3
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo Hans!hans.py hat geschrieben:Das Problem ist nur, daß nicht immer in jedem Feld der Ursprungstabelle ein Wert steht
Du hast als Quelle eine Tabelle mit einer **fixen** Feldanzahl. Auch das Ziel ist eine Tabelle mit einer **fixen** Feldanzahl.
Lösung: Hole **alle** benötigten Felder aus der Quelle und schreibe **alle** diese Felder in das Ziel.
Damit auch leere Werte (Im Datenbank-Slang auch NULL genannt.) in ein Feld der Zieltabelle geschrieben werden können, muss das Zielfeld darauf vorbereitet werden.
Dieses Beispiel erstellt eine Tabelle mit zwei Feldern. Beide Felder dürfen NULL enthalten:
Code: Alles auswählen
CREATE TABLE zieltabelle (
vorname TEXT NULL,
nachname TEXT NULL
)
Code: Alles auswählen
sql = """
INSERT INTO zieltabelle (
vorname, nachname
) VALUES (
?, ?
)"""
for row in quelldaten:
sqlite_conn.execute(sql, row)
sqlite_conn.commit()
Code: Alles auswählen
quelldaten = (
("EinVorname", "EinNachname"),
("NochEinVorname", None),
("WiederEinVorname", "WiederEinNachname"),
)
EDIT:
Gleich noch ausprobiert:
Code: Alles auswählen
>>> import sqlite3
>>> conn = sqlite3.connect(":memory:")
>>> sql="""
... CREATE TABLE zieltabelle (
... vorname TEXT NULL,
... nachname TEXT NULL
... )"""
>>> conn.execute(sql)
<sqlite3.Cursor object at 0x01B969B0>
>>> conn.commit()
>>> sql = """
... INSERT INTO zieltabelle (
... vorname, nachname) VALUES (
... ?, ?)"""
>>> quelldaten = (
... ("EinVorname", "EinNachname"),
... ("NochEinVorname", None),
... ("WiederEinVorname", "WiederEinNachname"),
... )
>>> for row in quelldaten:
... conn.execute(sql, row)
...
<sqlite3.Cursor object at 0x01B967D0>
<sqlite3.Cursor object at 0x01B969B0>
<sqlite3.Cursor object at 0x01B967D0>
>>> conn.commit()
>>> sql = """SELECT * from zieltabelle"""
>>> cur = conn.cursor()
>>> cur.execute(sql)
<sqlite3.Cursor object at 0x01B969E0>
>>> for row in cur:
... print repr(row)
...
(u'EinVorname', u'EinNachname')
(u'NochEinVorname', None)
(u'WiederEinVorname', u'WiederEinNachname')
>>>
mfg
Gerold

http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Vielen Dank Gerold für deine schnelle Hilfe.
Ich dachte, daß wenn man nicht explizit "NOT NULL" angibt, daß dann NULL-Werte zulässig sind. Ich werde es heute abend gleich mal ausprobieren.
Viele Grüße
Hans
Ich dachte, daß wenn man nicht explizit "NOT NULL" angibt, daß dann NULL-Werte zulässig sind. Ich werde es heute abend gleich mal ausprobieren.
Viele Grüße
Hans
So jetzt hab ich es ausprobiert, aber ich glaube nicht, daß es der Fehler war. Ich habe nämlich mittlerweile festgestellt, daß die leeren Felder der DBF-Datei beim auslesen in "0.0" umgewandelt werden. Das ist aber nicht gewünscht, da es sich bei der Datenbank um Daten einer Wetterstation handelt. Und wenn da der Sensor ausfällt bzw. nicht vorhanden ist, soll ja keine Temperatur von 0.0 Grad zurückgegeben werden. Das Problem ist aber erstmal zweitrangig.
Das andere ist, daß der Fehler wohl bei dem SQL Befehl "INSERT INTO" liegt.
Hier mal ein Stück Beispielcode:
Das habe ich so in einem Beispiel gesehen, aber ich vermute daß das mit den Doppelpunkten das Problem ist. Lasse ich sie weg, dann kommt der Fehler, daß z.B. die Spalte id nicht bekannt ist.
Ich habe dann ein anderes Besp. gesehen und den Code abgeändert:
Aber auch hier kommt ein Fehler, diesmal:
sqlite3.OperationalError: near "%": syntax error
Ich hoffe, daß mir auch diesmal jemand weiterhelfen kann. Falls nötig, kann ich noch die Tabellenerstellung posten, aber die funktioniert ja.
Viele Grüße Hans
Das andere ist, daß der Fehler wohl bei dem SQL Befehl "INSERT INTO" liegt.
Hier mal ein Stück Beispielcode:
Code: Alles auswählen
#Auslesen der DBF Daten
db = dbf.Dbf("NexusOrg.dbf")
connection = sqlite3.connect("WetterNexus.db")
cursor = connection.cursor()
zaehler = 0
for rec in db:
datum,zeit = du.wtopy(rec[0])
ch0_deg = rec[1]
ch0_rf = rec[2]
ch0_dew = rec[3]
ch1_deg = rec[4]
ch1_rf = rec[5]
ch1_dew = rec[6]
ch2_deg = rec[7]
ch2_rf = rec[8]
ch2_dew = rec[9]
ch3_deg = rec[10]
ch3_rf = rec[11]
ch3_dew = rec[12]
ch4_deg = rec[13]
ch4_rf = rec[14]
ch4_dew = rec[15]
ch5_deg = rec[16]
ch5_rf = rec[17]
ch5_dew = rec[18]
dru_loc = rec[19]
dru_abs = rec[20]
fcast = rec[21]
wchill = rec[22]
wtemp = rec[23]
wgust = rec[24]
wspeed = rec[25]
wdir = rec[26]
rain_sum = rec[27]
ecode = rec[28]
id = zaehler
zaehler += 1
print zaehler
print datum,zeit,ch0_deg,ch0_rf,ch0_dew,ch1_deg,ch2_deg,wtemp,dru_loc,dru_abs
# insert DATA in SQLite3 DB
cursor.execute("""INSERT INTO "WetterNexus"(id, date, time, t0, f0, td0,
t1, f1, td1, t2, f2, td2, t3, f3, td3, t4, f4, td4, t5, f5, td5,
druckl, druckabs, fc, wchill, wtemp, wgust, wspeed, wdir,
rainsum, errcode)
VALUES (:id, :datum, :zeit, :ch0_deg, :ch0_rf, :ch0_dew, :ch1_deg, :ch1_rf, :ch1_dew,
:ch2_deg, :ch2_rf, :ch2_dew, :ch3_deg, :ch3_rf, :ch3_dew,
:ch4_deg, :ch4_rf, :ch4_dew, :ch5_deg, :ch5_rf, :ch5_dew,
:dru_loc, :dru_abs, :fcast, :wchill, :wtemp, :wgust, :wspeed, :wdir, :rain_sum, :ecode)""")
cursor.close()
connection.close()
Ich habe dann ein anderes Besp. gesehen und den Code abgeändert:
Code: Alles auswählen
cursor.execute("""INSERT INTO WetterNexus(id, date, time, t0, f0, td0,
t1, f1, td1, t2, f2, td2, t3, f3, td3, t4, f4, td4, t5, f5, td5,
druckl, druckabs, fc, wchill, wtemp, wgust, wspeed, wdir,
rainsum, errcode)
VALUES (%d, %s, %s, %f, %d, %f, %f, %d, %f, %f, %d, %f, %f, %d, %f,
%f, %d, %f, %f, %d, %f, %f, %f, %d, %f, %f, %f, %f, %f, %f, %f)""", (id, datum,
zeit, ch0_deg, ch0_rf, ch0_dew, ch1_deg, ch1_rf, ch1_dew,
ch2_deg, ch2_rf, ch2_dew, ch3_deg, ch3_rf, ch3_dew,
ch4_deg, ch4_rf, ch4_dew, ch5_deg, ch5_rf, ch5_dew,
dru_loc, dru_abs, fcast, wchill, wtemp, wgust, wspeed, wdir, rain_sum, ecode))
sqlite3.OperationalError: near "%": syntax error
Ich hoffe, daß mir auch diesmal jemand weiterhelfen kann. Falls nötig, kann ich noch die Tabellenerstellung posten, aber die funktioniert ja.
Viele Grüße Hans
Du hast Platzhalter für Zeichenketten-Formatierung in die SQL-Anweisung geschrieben, das geht nicht. Es gibt ein paar Datenbankmodule die '%s' dafür benutzen, das hat aber nichts mit dem ``%``-Operator auf Zeichenketten zu tun.
Das `sqlite3`-Modul benutzt Fragezeichen als Platzhalter.
Das `sqlite3`-Modul benutzt Fragezeichen als Platzhalter.
Code: Alles auswählen
In [11]: from sqlite3 import dbapi2 as sqlite
In [12]: sqlite.paramstyle
Out[12]: 'qmark'