2015-09-13 28 views
0

從PostgreSQL文檔中,如果您在不指定模式的情況下執行INSERT,則它應該是public模式。PostgreSQL架構「www」不存在?

conn = psycopg2.connect(dbname = 'orion', 
       host = 'localhost', 
       port = 5432, 
       user = 'earthling', 
       password = 'mysupersecretpassword') 
sql = conn.cursor() 

def INSERT(table, info, text): 
    date = datetime.date.today() 
    query = "INSERT INTO %s (info, text, date) " \ 
     "VALUES (%s, %s, %s)" %(table, info, text, date) 
    sql.execute(query) 

INSERT("main", "www.capecod.edu", "test") 

出於某種原因,我看到以下錯誤?

psycopg2.ProgrammingError: schema "www" does not exist 

回答

3

您正在使用字符串插值來創建查詢。這是psycopg2執行什麼:

INSERT INTO main (info, text, date) 
    VALUES (www.capecod.edu, test, 2015-09-12) 

如果不是很明顯出了什麼問題在這裏,它是沒有價值的被引用。這裏是正確引用版本:

INSERT INTO main (info, text, date) 
    VALUES ('www.capecod.edu', 'test', '2015-09-12') 

錯誤是由未加引號www.capecod.edu引起的。由於這些點,它被解釋爲schema.table.column

執行此操作的「正確」方法是使用參數化查詢。

query = "INSERT INTO main (info, text, date) VALUES (%s, %s, %s)" 
params = (info, text, date) 
sql.execute(query, params) 

psycopg2將弄清楚應該引用什麼以及如何。這比你自己插入字符串更安全,這往往會讓你打開SQL注入攻擊。

http://initd.org/psycopg/articles/2012/10/01/prepared-statements-psycopg/

不幸的是,你不能只是折騰標識符,如作爲參數表名,因爲那時他們引述字符串值,這是不好的SQL語法。我找到了一個答案(python adds "E" to string),它指向psycopg2.extensions.AsIs作爲安全地將諸如表名之類的標識符作爲參數傳遞的方式。不過,我無法在測試中完成這項工作。

如果你走的是AsIs路由,你應該小心檢查表名是否有效,如果它們以某種方式來自用戶輸入。類似於

valid_tables = ["main", "foo", "bar", "baz"] 

if table not in valid_tables: 
    return False 
+0

這不會像書面的那樣工作。你必須自己插入字符串,因爲psycopg2不知道它是一個標識符而不是文字。 –

+0

@CraigRinger謝謝,我沒有抓到。實際上,您可以將表名作爲參數傳遞,您只需要更加謹慎......我將編輯答案。 –

+0

在名稱周圍添加''後,似乎只有工作,我沒有看到我的表中的條目?這是因爲我需要使用參數總是?或者,也許日期需要PostgreSQL風格而不是Python風格? – htmlfarmer