Seite 1 von 1
Platzhalter in MySQLdb
Verfasst: Sonntag 31. Mai 2009, 11:29
von Caldar
Gibt es eine Möglichkeit, bei CREATE TABLE-Befehlen Platzhalter zu verwenden. Ich will eine Tabelle abhängig von der Anzahl und den Namen einer Liste erstellen lassen.
Die Liste sehe z.B. so aus
Nun will ich folglich eine Tabelle erstellen, die aus 2 Spalten besteht, in MySQL-Syntax also:
CREATE TABLE (`abc` VARCHAR(20), `def` VARCHAR(20))
Wenn ich nun aber folgendes versuche:
Code: Alles auswählen
curs.executemany("""CREATE TABLE temp(
%s VARCHAR(30),
%s VARCHAR(30)
)""", x)
schlägt dies fehl. Kann es sein, dass der executemany-Befehl nur bei SELECT-Queries funktioniert und ich gar keine Möglichkeit habe, dies zu realisieren?
Verfasst: Sonntag 31. Mai 2009, 11:54
von Caldar
Ich habs jetzt so gelöst, indem ich mir aus der Liste eine SQL-Query als String zusammengebaut habe, also:
Code: Alles auswählen
sql = "CREATE TABLE temp (%s VARCHAR(30), %s VARCHAR(30))" % ("abc","def")
und diese dann per
ausführe
Edit:
Das Problem ist aber immer noch, dass ja meine Liste eine unterschiedliche Anzahl von Einträgen enthalten kann und ich ja so viele Spalten erstellen will, wie ich EIntrage in der Liste habe.
Verfasst: Sonntag 31. Mai 2009, 12:02
von BlackJack
@Caldar: Die Platzhalter sind nur für Werte, weil die entsprechend der Regeln für Werte "ecape"t werden.
Ich denke Du hast `executemany()` missverstanden. Es gibt keine Beschränkung auf bestimmte SQL-Konstrukte, ausser das Platzhalter für Werte darin vorkommen sollten. Die ganze Anweisung wird mit jedem Satz von Werten ausgeführt, der in dem "iterable" steht, welches übergeben wird. Der Gedanke dabei ist, das halbwegs intelligente DBMS die SQL-Anweisung nur einmal Parsen,in internen "Code" übersetzen, und dann auf die Werte-"Sätze" anwenden, statt für jeden Satz von Werten die SQL-Anfrage erneut zu verarbeiten.
Verfasst: Sonntag 31. Mai 2009, 12:37
von Caldar
Okay, es müsste also auch für CREATE TABLE-Befehle funktionieren mit den executemany-Befehl. Der Platzhalter-Gedanke war mir schon klar, nur dass es mit meinem Bsp. nicht funktionirt, irritiert mich.
Ich kann auch mal den kompletten Code posten, vielleicht erkennst Du da einen Fehler, den ich mache:
Code: Alles auswählen
fobj = open("D:\\file.csv", "r")
cols = fobj.readline()
cols = cols.strip()
col_list = cols.rsplit(";")
fobj.close()
conn = MySQLdb.connect("localhost", "root", db="xyz")
curs = conn.cursor()
curs.executemany("""CREATE TABLE temp (%s VARCHAR(30), %s VARCHAR(30))""",col_list)
Die Fehlermeldung, die ich bekomme, ist:
TypeError: not enough arguments for format string
col_list sieht in der Konsole so aus, wenn ich ihn über eine for Schleife ausgebe:
"abc"
"def"
Verfasst: Sonntag 31. Mai 2009, 13:02
von cofi
Ich glaube du hast es immernoch nicht verstanden.
`executemany` führt das Statement mehrmals aus, das Iterable muss aber ein komplettes Statement bereitstellen, dh in deinem Fall pro Iteration 2 Werte liefern.
Für deinen Zweck brauchst du nur ein einfaches `execute`. Oder, wenn du wirklich mehrere Tabellen erzeugen willst ein Iterable mit Paaren wie zb ("abc", "def").