2009-11-14 24 views
16

我會採取最簡單的SQL函數爲例:如果我複製爲什麼不是psycopg2執行我的任何SQL函數? (IndexError:元組索引超出範圍)

CREATE OR REPLACE FUNCTION skater_name_match(INTEGER,VARCHAR) 
RETURNS BOOL AS 
$$ 
    SELECT $1 IN (SELECT skaters_skater.competitor_ptr_id FROM skaters_skater 
    WHERE name||' '||surname ILIKE '%'||$2||'%' 
    OR surname||' '||name ILIKE '%'||$2||'%'); 
$$ LANGUAGE SQL; 

並粘貼到PSQL(PostgreSQL的外殼),那麼它的執行沒有任何問題。

如果我寫了一個Python代碼所示(帶有一個真正的數據庫名稱和課程的用戶):

import psycopg2 

sql_function_above = '''CREATE OR REPLACE FUNCTION skater_name_match(INTEGER,VARCHAR) 
RETURNS BOOL AS 
$$ 
    SELECT $1 IN (SELECT skaters_skater.competitor_ptr_id FROM skaters_skater 
    WHERE name||' '||surname ILIKE '%'||$2||'%' 
    OR surname||' '||name ILIKE '%'||$2||'%'); 
$$ LANGUAGE SQL;''' 

try: 
    connection = psycopg2.connect("dbname='x' user='x' host='localhost' password='x'"); 
except: 
    print "I am unable to connect to the database" 

cursor = connection.cursor() 
cursor.execute(sql_function_above) 

似乎執行(它不給我一個錯誤)但是當我查看數據庫時,函數不在那裏。

當我嘗試把它變成一個應用程序/ SQL/model.sql文件我碰到下面的錯誤執行syncdb期間執行在Django代碼:

IndexError: tuple index out of range 

當我嘗試寫我自己的管理。 py命令會執行sql,我得到相同的錯誤。

這是怎麼回事?非常感謝任何能夠說明這一點的人:)當談到Python和Django時,我仍然是一個新手,所以我可能忽略了一些明顯的東西。

+1

您是否可以在「遊標」中添加您正在執行的實際語句。執行(sql_function_above)「(或者顯示你定義'sql_function_above'的地方,如果你真的想用這個標識符) – 2009-11-14 17:18:47

+1

向我們展示你如何在你的python代碼中定義sql_function_above' – nos 2009-11-14 18:44:12

+0

對不起,這是我的簡化。嘗試以各種不同的方式編寫變量,我也嘗試從sql文件中讀取文本,所有這些都產生了相同的錯誤,現在我編寫變量編輯到原始問題中的許多方法之一。回覆 - 這是我第一次使用stackoverflow.com,來自你們的回覆的樂於助人和速度是驚人的:) – 2009-11-16 12:09:12

回答

28

 
connection.set_isolation_level(0) 

更多信息默認情況下psycopg2標識使用%符號參數佔位符(通常你必須%s在字符串中)。

所以,如果你使用cursor.execute('... %s, %s ...', (arg1, arg2))那麼那些%s分別變成arg1和arg2的值。

但既然你撥打:cursor.execute(sql_function_above),沒有額外的參數,和你的SQL包括%跡象庫試圖找到傳遞給函數的第二個參數 - 這是超出範圍,因此一個IndexError。

解決方案:而不是使用%,在您的SQL變量中寫入%%。在發送到PostgreSQL之前,它會被轉換爲文字%

1

索引超出範圍意味着您試圖訪問(例如)只有兩個元素的元組的第三個元素。請注意,Python的索引從0開始,因此名爲myTuple的兩元素元組將具有元素myTuple [0]和myTuple [1],但不包含元素myTuple [2]。

+0

是的......這就是讓我更加困惑的事情聽起來像是psycopg2庫中有一個元組,罪魁禍首,那就意味着psycopg2庫中有一個bug(或者我跳到了錯誤的結論?)但是如果是這樣,我的SQL有什麼特別的地方會打破一個大多數pe ople找到完美穩定? 這裏的問題的一部分是,我甚至無法隔離究竟哪裏出了問題,因爲當我嘗試在Django之外執行SQL時,我不會收到錯誤消息,但SQL不會執行。 – 2009-11-14 17:25:57

+0

您的代碼確實包含諸如$ 2和%之類的litterals。一些數據庫庫可能會將thoe解釋爲參數佔位符。在python的情況下,你可能只是沒有提交交易。 – nos 2009-11-14 18:45:59

3

看起來你是不是在提交事務:

嘗試把:

 
cursor.execute("COMMIT") 

最後一行之後,看看是否可行。

您還可以設置隔離級別自動提交,如:在這個answer

+0

雖然元組錯誤與事務沒有任何關係,但是一旦%符號問題被刪除,sql函數仍然沒有加載,這當然是原因,所以非常感謝你的回答:) – 2009-11-16 12:32:31

+0

PS:你應該使用'connection.commit()'而不是手動執行「COMMIT」 - 這樣psycopg2知道當前的事務狀態。 – intgr 2011-12-13 14:57:42

相關問題