简体   繁体   English

编程错误:function lower(bigint) 不存在(Django、AWS RDS、PostgreSQL)

[英]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.

相关问题 将 csv 文件从 s3 导入 rds PostgreSQL 数据库 > 错误:模式“aws_commons 不存在 - Importing a csv file from s3 into rds PostgreSQL Database > Error: schema "aws_commons does not exist AWS Lambda 与 RDS Postgresql - 未知问题 - AWS Lambda with RDS Postgresql - Unknown Issue 无法将aws RDS连接到本地django - Unable to connect aws RDS to django local 将 Heroku 与 AWS RDS PostgreSQL 集成时,获取 stream 的“不一致 state” - Get `Inconsistent state for stream ` when integrating Heroku with AWS RDS PostgreSQL 如何更改 Postgresql 的 AWS RDS 中的“数据库名称”? - How can I change the "Database Name" in AWS RDS for Postgresql? PostgreSQL 连接尝试超时错误的 AWS RDS - AWS RDS for PostgreSQL Connection attempt timed out error 如何从 AWS CLI 连接到 AWS RDS PostgreSql 实例 - How to connect to AWS RDS PostgreSql Instance from AWS CLI CDC 和副本使用 AWS DMS 从 oracle PeopleSoft 到 RDS postgreSQL - CDC and replica using AWS DMS from oracle PeopleSoft to RDS postgreSQL 将 CSV 导入 postgreSQL 中的表,忽略重复项 - Amazon AWS/RDS - Import CSV to table in postgreSQL ignoring duplicates - Amazon AWS/RDS Django 和 postgresql 在 aws elastic beanstalk 上的部署 - Django with postgresql deployment on aws elastic beanstalk
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM