2014-12-04 17 views
11

Ich versuche Spalten zu einer Tabelle hinzufügen psycopg2Pass Spaltenname als Parameter PostgreSQL mit psycopg2

row1 unter Verwendung ist eine Liste der Spaltennamen in der Tabelle hinzugefügt werden. Ich kann es manuell tun, aber wenn ich es programmatisch mache, erhalte ich einen Fehler.

for c in row1: 
    cur.execute("ALTER TABLE HHV2PUB ADD COLUMN %s text", (c,)) 

Der Fehler ist:

cur.execute("ALTER TABLE HHV2PUB ADD COLUMN %s text", (c,)) 
psycopg2.ProgrammingError: syntax error at or near "'HOUSEID'" 
LINE 1: ALTER TABLE HHV2PUB ADD COLUMN 'HOUSEID' text 

Meine Vermutung ist, dass es etwas mit den einfachen Anführungszeichen ''

+0

dass einfache Anführungszeichen in ' 'HOUSEID'' (% s) das Problem –

+0

@varchar sein sollte: Ja, und diese einfache Anführungszeichen gibt es, da die OP verwendet SQL-Parameter. –

Antwort

15

Ab psycopg 2.7 gibt es die sicheren sql module:

from psycopg2 import sql 

query = sql.SQL("alter table t add column {} text") 

row1 = ('col1', 'col2') 
for c in row1: 
    cursor.execute(query.format(sql.Identifier(c))) 

Mit 2.6 und früher:

Verwendung psycopg2.extensions.AsIs

Adapter conform to the ISQLQuote protocol useful for objects whose string representation is already valid as SQL representation.

import psycopg2 
from psycopg2.extensions import AsIs 

conn = psycopg2.connect("host=localhost4 port=5432 dbname=cpn") 
cursor = conn.cursor() 

query = "alter table t add column %s text" 

row1 = ('col1', 'col2') 
for c in row1: 
    cursor.execute(query, (AsIs(c),)) 
conn.commit() 
+3

Beachten Sie, dass dies nicht sicherer ist als die direkte Interpolation des Objektnamens. –

+0

Mit 'sql.Identifier()' ist sicher, ja: https://github.com/psycopg/psycopg2/issues/577 Aber 'AsIs()' ist nicht. –

5

Sie nicht SQL-Parameter für SQL Objektnamen zu tun verwenden können. SQL-Parameter geben Werte explizit an, sodass sie nicht als solche interpretiert werden können. das ist einer der Hauptgründe, SQL-Parameter zu verwenden, andernfalls.

Sie müssen hier die String-Interpolation verwenden. Seien Sie extrem vorsichtig, dass Sie nicht von Benutzereingaben mit c hier zu produzieren:

for c in row1: 
    cur.execute("ALTER TABLE HHV2PUB ADD COLUMN %s text" % c) 

psycopg2 gibt Ihnen eine Methode Parameter markieren als ‚bereits entkommen‘ mit psycopg2.extensions.AsIs(), aber die Absicht ist, dafür verwendet werden auf bereits Daten stattdessen entkommen.

Eine viel bessere Idee ist es, die psycopg2.sql extension zu verwenden richtige Kennung Entkommen zu verwalten:

from psycopg2 import sql 

for c in row1: 
    cur.execute(
     sql.SQL("ALTER TABLE HHV2PUB ADD COLUMN {} text").format(
      sql.Identifier(c)))