[英]ProgrammingError: function lower(bigint) does not exist (Django, AWS RDS, PostgreSQL)
In my Django Rest Framework project, I have a custom filter_backends that allows filtering by case insensitively:在我的 Django Rest Framework 项目中,我有一个自定义的 filter_backends 允许不区分大小写地进行过滤:
class CaseInsensitiveOrderingFilter(OrderingFilter):
def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request, queryset, view)
if ordering:
new_ordering = []
for field in ordering:
# field = str(field)
print(Lower(field))
if field.startswith('-'):
new_ordering.append(Lower(field[1:]).desc())
else:
new_ordering.append(Lower(field).asc())
return queryset.order_by(*new_ordering)
return queryset
This works fine in development.这在开发中工作正常。
Now I hosted the django app on elastic beanstalk and I configured a postgresql database via amazon relational database service (RDS).现在,我在弹性 beantalk 上托管了 django 应用程序,并通过亚马逊关系数据库服务 (RDS) 配置了一个 postgresql 数据库。
When I try now to call the API, I get this error:当我现在尝试拨打 API 时,出现以下错误:
ProgrammingError at /api/profile_list/ function lower(bigint) does not exist LINE 1: ..."."author_id") GROUP BY "user_user"."id" ORDER BY LOWER(COUN...
ProgrammingError at /api/profile_list/ function lower(bigint) does not exist LINE 1: ..."."author_id") GROUP BY "user_user"."id" ORDER BY LOWER(COUN...
HINT: No function matches the given name and argument types.
提示:没有 function 匹配给定的名称和参数类型。 You might need to add explicit type casts.
您可能需要添加显式类型转换。
This error appears only in the RDS deployment.此错误仅出现在 RDS 部署中。
I tried to type cast the fields in django with:我尝试在 django 中输入以下字段:
field = str(field)
But this is not working.但这是行不通的。 Is there any way to allow caseinsensitive ordering without the lower function, or how can I conditionally check if it is a number (and cast then?) or a text abd
有什么方法可以在没有较低的 function 的情况下允许不区分大小写的排序,或者我如何有条件地检查它是一个数字(然后转换?)或文本 abd
You get the error because you use Lower
on a field which is perhaps an IntegerField
or something else.您收到错误是因为您在可能是
IntegerField
或其他东西的字段上使用了Lower
。 You want to be checking what your field is before actually using Lower
:您想在实际使用
Lower
之前检查您的字段是什么:
from django.db import models
def get_field_type(field_name, queryset):
stripped_field_name = field_name.lstrip('-')
if stripped_field_name in queryset.query.annotations:
return queryset.query.annotations[stripped_field_name].output_field
return queryset.model._meta.get_field(stripped_field_name)
class CaseInsensitiveOrderingFilter(OrderingFilter):
def filter_queryset(self, request, queryset, view):
ordering = self.get_ordering(request, queryset, view)
if ordering:
new_ordering = []
for field in ordering:
if not isinstance(get_field_type(field, queryset), (models.CharField, models.TextField)):
# Most of the character type fields inherit from CharField.
# I might miss a few fields here so you would need to make sure
new_ordering.append(field)
elif field.startswith('-'):
new_ordering.append(Lower(field[1:]).desc())
else:
new_ordering.append(Lower(field).asc())
return queryset.order_by(*new_ordering)
return queryset
To answer the additional question from this comment :要回答此评论中的其他问题:
I wonder why this code is working with my local db.sqlite, but not on RDS.
我想知道为什么这段代码适用于我的本地 db.sqlite,但不适用于 RDS。 ...
...
The PostgreSQL lower
function (as used on RDS) only accepts text values . PostgreSQL
lower
function(在 RDS 上使用) 只接受文本值。
The SQLite lower
function also accepts integers, although it is not explicitly mentioned in the docs . SQLite
lower
function 也接受整数,尽管文档中没有明确提及。
This probably has to do with the fact that "SQLite uses a more general dynamic type system."这可能与“SQLite 使用更通用的动态类型系统”这一事实有关。 Also see this SO answer .
另请参阅此 SO 答案。
This illustrates why it can be advantageous to use the same RDBMS both locally and in production.这说明了为什么在本地和生产中使用相同的 RDBMS 是有利的。
NOTE:笔记:
Although SQLite does not complain when you do something like虽然 SQLite 在你做类似的事情时不会抱怨
... ORDER BY LOWER("my_integer_field")
the result can be surprising, because it will be in lexicographic order .结果可能会令人惊讶,因为它将按字典顺序排列。
For example例如
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
will be sorted as text, resulting in将被排序为文本,导致
[1, 10, 11, 12, 2, 3, 4, 5, 6, 7, 8, 9]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.