姜戈1.5
PostgreSQL 9.2版
心理学2.4.6
我正在使用QuerySet API的额外功能,以便能够为Postgres使用来自多维数据集扩展的函数-我知道由于可移植性的原因,额外功能不是很好,但是无论如何我不会使用其他数据库(不是在Postgres之后,不!)。所以问题是,我从以下代码中得到了错误的SQL查询:

return self.select_related('item_place').extra(
            select={ 'distance': 'round(earth_distance(ll_to_earth(%s, %s), ll_to_earth(%s.latitude, %s.longitude))::numeric, 0)' },
            select_params=[latitude, longitude, ItemPlace._meta.db_table, ItemPlace._meta.db_table],
            where=['round(earth_distance(ll_to_earth(%s, %s), ll_to_earth(%s.latitude, %s.longitude))::numeric, 0) <= %s'],
            params=[latitude, longitude, ItemPlace._meta.db_table, ItemPlace._meta.db_table, radius])

psycopg2似乎用单引号将表名括起来,这对于Postgres是不正确的,在正在执行的脚本中,我可以看到:
round(earth_distance(ll_to_earth(%s, %s), ll_to_earth('item_place'.latitude, 'item_place'.longitude))::numeric, 0)

我应该使用表名,因为我在另一个表中有纬度和经度,如果没有它,我将得到“ambigous column”错误。现在我不知道,也许我做的smth是完全错误的,这就是为什么我会犯这个错误,或者可能是psycopg2中的一个bug?有什么想法吗?

最佳答案

根据the doc,使用paramsselect_params指示Psycopg2引用参数。它不用于引用表名(这是通过双引号完成的)。
引用the doc of Psycopg2
只有变量值应该通过此方法绑定:它不应该
用于设置表或字段名。对于这些元素,普通字符串
在运行execute()之前应使用格式化。
此外,我们通常不会使用需要双引号作为表名的标识符,ref the comment of this answer。因此,在代码中直接使用表名是安全的:

return self.select_related('item_place').extra(
        select={ 'distance': 'round(earth_distance(ll_to_earth(%s, %s), ll_to_earth({tbl}.latitude, {tbl}.longitude))::numeric, 0)'.format(tbl=ItemPlace._meta.db_table) },
        select_params=[latitude, longitude],
        where=['round(earth_distance(ll_to_earth(%s, %s), ll_to_earth({tbl}.latitude, {tbl}.longitude))::numeric, 0) <= %s'.format(tbl=ItemPlace._meta.db_table)],
        params=[latitude, longitude])

关于django - Django Postgres psycopg2错误的脚本生成-引用表名,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15684769/

10-13 06:43