Seite 1 von 1

executemany()

Verfasst: Donnerstag 3. August 2006, 14:07
von _Sebastian_
Hallo,

ich habe ein Problem mit executemany() von pysqlite.
Ein direkt aus dem Usage-Guide entnommenes Beispiel funktioniert:

Code: Alles auswählen

from pysqlite2 import dbapi2 as sqlite

con = sqlite.connect("test")

cur = con.cursor()

newPeople = (
    ('Lebed'       , 53),
    ('Zhirinovsky' , 57),
  )

cur.executemany("insert into people (name_last, age) values (?, ?)", newPeople) 

# The changes will not be saved unless the transaction is committed explicitly:
con.commit()
Ändere ich das aber ein wenig ab, bekomme ich die Fehlermeldung
Traceback (most recent call last):
File "test.py", line 12, in ?
cur.executemany("insert into people (name_last) values (?)", newPeople)
pysqlite2.dbapi2.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 5 supplied.
Mein geänderter Code:

Code: Alles auswählen

from pysqlite2 import dbapi2 as sqlite

con = sqlite.connect("test")

cur = con.cursor()

newPeople = (
    ('name1'),
    ('name2'),
  )

cur.executemany("insert into people (name_last) values (?)", newPeople) 

# The changes will not be saved unless the transaction is committed explicitly:
con.commit()
Woran liegt das? Gibt es vielleicht irgendwo eine genaue Referenz, was ich executemany() als 2. Parameter übergeben darf?

Verfasst: Donnerstag 3. August 2006, 14:21
von DatenMetzgerX

Code: Alles auswählen

from pysqlite2 import dbapi2 as sqlite

con = sqlite.connect("mydb")

cur = con.cursor()

newPeople = ({'name_last': 'Lebed', 'age': 53},
    {'name_last':'Zhirinovsky' ,'age':  57}
  )

cur.executemany("insert into people (name_last, age) values (?, ?)", newPeople)

# The changes will not be saved unless the transaction is committed explicitly:
con.commit()
sollte so gehen, nicht getestet

Verfasst: Donnerstag 3. August 2006, 14:31
von _Sebastian_
Aber dein Code fügt doch genau das gleiche in die DB ein, wie das Beispiel aus dem Usage Guide, oder?

Was ich eigentlich wissen wollte:
Ich habe ein Tupel/Liste, z.b. testlist = ['name1', 'name2'] und will das executemany() übergeben - aber warum funktioniert das nicht?

Verfasst: Donnerstag 3. August 2006, 14:40
von BlackJack
`executemany()` braucht als zweiten Parameter ein "iterable" über Sequenzen. Du hast in Deinem zweiten Versuch aber kein Tupel mit Tupeln übergeben sondern nur ein Tupel mit zwei Zeichenketten! Die Klammern "machen" keine Tupel, sondern die Kommata. Ein Tupel mit einem Element muss also so aussehen: ('hallo',). Man beachte das Komma!

Verfasst: Donnerstag 3. August 2006, 18:36
von _Sebastian_
Bin mir nicht ganz sicher, ob ich deine Erklärung verstanden habe :)
Läuft es auf ein verschachtelte Arrays hinaus?

Verfasst: Donnerstag 3. August 2006, 18:50
von BlackJack
Sozusagen. Du kannst aber auch Tupel nehmen. Du musst sie nur richtig deklarieren:

Code: Alles auswählen

n [22]: type( ('hallo') )
Out[22]: <type 'str'>

In [23]: type( ('hallo',) )
Out[23]: <type 'tuple'>
Das Komma fehlte in Deinem Beispiel das nicht funktionierte. Ohne das Komma hast Du nur ein Tupel mit zwei Zeichenketten und kein Tupel mit zwei Tupeln die jeweils eine Zeichenkette enthalten.

Verfasst: Donnerstag 3. August 2006, 21:03
von Joghurt
BlackJack hat geschrieben:Ohne das Komma hast Du nur ein Tupel mit zwei Zeichenketten und kein Tupel mit zwei Tupeln die jeweils eine Zeichenkette enthalten.
Und deshalb wurde auch über die einzelnen Buchstaben des Strings iteriert. Daher kommt auch das "there are 5 supplied.", denn "demo1" hat 5 Buchstaben.

Code: Alles auswählen

>>> for x in ("Hallo"): print x
H
a
l
l
o
>>> for x in ("Hallo",): print x
Hallo

Verfasst: Donnerstag 3. August 2006, 21:06
von _Sebastian_
In der Tat, jetzt funktionierts und verstanden habe ich es auch :-)

Vielen Dank BlackJack und Joghurt