2014-12-04 15 views
11

Tôi đang cố gắng để thêm các cột vào một bảng sử dụng psycopg2tên cột đèo như tham số để PostgreSQL sử dụng psycopg2

row1 dưới đây là danh sách các tên cột được thêm vào bảng. Tôi có thể làm điều đó bằng tay nhưng khi tôi cố gắng làm điều đó một cách lập trình tôi nhận được một lỗi.

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

Lỗi này là:

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 

tôi đoán là nó có cái gì để làm với các dấu nháy đơn ''

+0

rằng dấu nháy đơn trong ' 'HOUSEID'' (% s) nên là vấn đề –

+0

@varchar: Vâng, và những dấu nháy đơn ở đó vì OP sử dụng các tham số SQL. –

Trả lời

15

Tính đến Psycopg 2.7 có an toàn 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))) 

Với 2.6 và trước đó:

Sử dụng 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

Lưu ý rằng điều này không an toàn hơn bằng cách sử dụng nội suy thẳng đứng của tên đối tượng. –

+0

Sử dụng 'sql.Identifier()' là an toàn, có: https://github.com/psycopg/psycopg2/issues/577 Nhưng 'AsIs()' thì không. –

5

Bạn không thể sử dụng các tham số SQL cho tên đối tượng SQL. Các tham số SQL trích dẫn các giá trị một cách rõ ràng để chúng không thể được hiểu như vậy; đó là một trong những lý do chính để sử dụng các tham số SQL nếu không thì.

Bạn sẽ phải sử dụng nội suy chuỗi tại đây. Hãy cực kỳ cẩn thận rằng bạn đang không sử dụng đầu vào dùng để sản xuất c đây:

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

Psycopg2 không cung cấp cho bạn một phương pháp để đánh dấu các thông số như 'đã thoát khỏi' với psycopg2.extensions.AsIs(), nhưng mục đích là cho điều này sẽ được sử dụng thay vào đó, đã xóa dữ liệu.

Một ý tưởng tốt hơn nhiều là sử dụng psycopg2.sql extension để quản lý đúng định thoát:

from psycopg2 import sql 

for c in row1: 
    cur.execute(
     sql.SQL("ALTER TABLE HHV2PUB ADD COLUMN {} text").format(
      sql.Identifier(c))) 
Các vấn đề liên quan