2014-12-04 8 views
11

sto cercando di aggiungere colonne a una tabella utilizzando psycopg2Passo nome della colonna come parametro per PostgreSQL usando psycopg2

row1 qui di seguito è un elenco di nomi di colonna da aggiungere alla tabella. Posso farlo manualmente ma quando provo a farlo programmaticamente ottengo un errore.

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

L'errore è:

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 

La mia ipotesi è che ha qualcosa a che fare con le virgolette singole ''

+0

che apici in ' 'HOUSEID'' (% s) dovrebbe essere la @varchar problema –

+0

: Sì, e quelle singole citazioni sono lì perché le OP utilizzato parametri SQL. –

risposta

15

A partire dal psycopg 2.7 c'è la cassaforte 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))) 

Con 2.6 e precedenti:

Utilizzare 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

Si noti che non è più sicuro dell'utilizzo dell'interpolazione diretta del nome dell'oggetto. –

+0

L'uso di 'sql.Identifier()' è sicuro, sì: https://github.com/psycopg/psycopg2/issues/577 Ma 'AsIs()' non lo è. –

5

Non è possibile utilizzare parametri SQL per i nomi degli oggetti SQL. I parametri SQL citano i valori esplicitamente in modo che non possano essere interpretati come tali; questo è uno dei motivi principali per utilizzare i parametri SQL altrimenti.

Qui dovrai utilizzare l'interpolazione delle stringhe. Puoi essere estremamente attenti che non si utilizza l'input dell'utente per produrre c qui:

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

psycopg2 ti dà un metodo per contrassegnare i parametri come 'già scappato' con psycopg2.extensions.AsIs(), ma l'intenzione è per questo da utilizzare su già scappato dati invece.

una migliore idea è quella di utilizzare il psycopg2.sql extension per gestire corretto identificativo fuga:

from psycopg2 import sql 

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