SQLAlchemy类型装饰器失败,`对象没有属性'self_group'

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQLAlchemy类型装饰器失败,`对象没有属性'self_group'相关的知识,希望对你有一定的参考价值。

我有一个使用SQLAlchemy 1.1的遗留Python 3代码库,出于“原因”,它有一个类:

class jsonbool(str):
   def __bool__(self):
       return True if self == 'true' else False

此类用于SQLAlchemy过滤器表达式,例如query.filter(SomeTable.ABooleanColumn == anInstanceOfjsonbool).all()。这在1.1中运行良好,因为使用了jsonbool类型的字符串表示(例如truefalse)。

在SQLAlchemy 1.2中,他们一边增加了额外的检查,以防止某些类型的伪装成为布尔值。上面的工作现在失败了sqlalchemy.exc.StatementError: (builtins.TypeError) Not a boolean value: 'false'false实际上有一个jsonbool的例子)。

我想用SQLAlchemy TypeDecorator来纠正这个问题,这允许我在表达式中绑定时将参数转换为布尔值。我的原型只是为了让自定义类型的装饰工作,有:

import sqlalchemy.types as types

class jsonbool(str, types.TypeDecorator):
   impl = types.Boolean

   def __bool__(self):
       return True if self == 'true' else False

唉,这个和我尝试的所有类似的结果在尝试运行查询时导致AttributeError: 'Boolean' object has no attribute 'self_group'(其中s/Boolean/WhateverImplIPick)。我也尝试使用具有相同结果的UserDefinedType

当我将它作为SQLAlchemy表达式的一部分使用时,如何更改jsonbool类型的行为?

答案

TypeDecorator是一种SQLAlchemy类型,类似于StringBoolean,其实例用于声明列或表达式的类型,如

foo = Column(String, ...)
bar = Column(jsonbool, ...)

使用这样的类型作为值是没有意义的,所以就像strString分开一样,你需要一个与JsonBool分开的jsonbool类,如下所示:

class JsonBool(TypeDecorator):
    impl = Boolean

    def process_bind_param(self, value, dialect):
        return value == "true"

    def process_result_value(self, value, dialect):
        return jsonbool("true") if value else jsonbool("false")

当然,您需要更改SomeTable.ABooleanColumn的定义才能使用此类型:

ABooleanColumn = Column(JsonBool, ...)

这可能是您的代码库的高级订单,在这种情况下,您可以使SQLAlchemy为custom compilation对象执行jsonbool

class jsonbool(str, ColumnElement):
    def __bool__(self):
        return True if self == 'true' else False

@compiles(jsonbool)
def _compile_jsonbool(element, compiler, **kwargs):
    if element:
        return compiler.visit_true(None)
    else:
        return compiler.visit_false(None)

以上是关于SQLAlchemy类型装饰器失败,`对象没有属性'self_group'的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy模型中的进程字段(使用flask_sqlalchemy)

动态创建的方法和装饰器,得到错误 'functools.partial' 对象没有属性 '__module__'

mongoose @prop() 装饰器类型:模式定义中的对象_NestJS

使用类装饰器添加 sqlalchemy 重建器方法

SQLAlchemy学习-10. validates()校验器

数据库进阶实践-事件监听