Mon*_*lik 16 python sql django postgresql psycopg2
我将以最简单的SQL函数为例:
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;
Run Code Online (Sandbox Code Playgroud)
如果我将其复制并粘贴到psql(PostgreSQL的shell)中,那么它会毫无问题地执行.
如果我像这样编写一段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)
Run Code Online (Sandbox Code Playgroud)
它似乎执行(它不会给我一个错误),但当我查看数据库时,函数不存在.
当我尝试通过将它放入app/sql/model.sql文件来执行Django中的代码时,我在syncdb期间收到以下错误:
IndexError: tuple index out of range
Run Code Online (Sandbox Code Playgroud)
当我尝试编写自己的执行sql的manage.py命令时,我得到了同样的错误.
这里发生了什么?非常感谢任何可以阐明这一点的人:)在Python和Django方面,我仍然是一个新手,所以我可能忽略了一些明显的东西.
int*_*tgr 30
默认情况下,psycopg2使用%
符号标识参数占位符(通常%s
在字符串中有).
所以,如果你使用cursor.execute('... %s, %s ...', (arg1, arg2))
那么那些%s
分别变成了arg1和arg2的值.
但是,因为你调用:cursor.execute(sql_function_above)
,没有额外的参数,并且你的SQL包含%
符号,库试图找到传递给函数的第二个参数 - 它超出范围,因此是一个IndexError.
解决方案:而不是使用%
,写入%%
您的SQL变量.在将%
它发送到PostgreSQL之前,它会被翻译成文字.