【问题标题】:SQLAlchemy: operator LIKE and custom typesSQLAlchemy:运算符 LIKE 和自定义类型
【发布时间】:2015-04-10 22:03:15
【问题描述】:

我使用 sqlalchemy ORM。我有以下自定义列类型和表映射类:

class JSONEncodedDict(TypeDecorator):
    impl = VARCHAR

    def process_bind_param(self, value, dialect):
        if value is not None:
            value = json.dumps(value)

        return value

    def process_result_value(self, value, dialect):
        if value is not None:
            value = json.loads(value)
        return value

Base = declarative_base()
class Task(Base):
    __tablename__ = 'tasks'

    id = Column(INT, primary_key=True)
    description = Column(JSONEncodedDict)
    created = Column(TIMESTAMP)
    updated = Column(TIMESTAMP)

我想使用运算符'like'查询对象:

tasks = session.query(Task).filter(Task.description.like("%some pattern%")).all()

但据我所知,方法process_bind_param 也转换了like 运算符的参数。所以在 sql trace 中我看到了

...WHERE description LIKE '"%some pattern%"'

而不是

...WHERE description LIKE '%some pattern%'

所以没有匹配的行。

如何以我想要的方式使用LIKE 运算符执行查询?

【问题讨论】:

    标签: python postgresql orm sqlalchemy


    【解决方案1】:

    使用literal() 可以绕过自动类型处理(或使用type_ 参数强制自己处理):

    Task.description.like(literal("%some pattern%"))
    

    【讨论】:

    • 如果在自定义类型中使用了like 子句,有没有办法访问?
    【解决方案2】:

    另一种方法是使用cast()type_coerce() 将列强制转换为文本形式,然后再尝试使用likecontains 等运算符或其他内容:

    from sqlalchemy import type_coerce, String
    
    stmt = select([my_table]).where(
        type_coerce(my_table.c.json_data, String).like('%foo%'))
    

    或者您可以在自定义类型类定义中执行此操作:

    from sqlalchemy.sql import operators
    from sqlalchemy import String
    
    class JSONEncodedDict(TypeDecorator):
    
        impl = VARCHAR
    
        def coerce_compared_value(self, op, value):
            if op in (operators.like_op, operators.notlike_op):
                return String()
            else:
                return self
    
        def process_bind_param(self, value, dialect):
            if value is not None:
                value = json.dumps(value)
    
            return value
    
        def process_result_value(self, value, dialect):
            if value is not None:
                value = json.loads(value)
            return value
    

    参考:doc

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 2014-05-16
      • 1970-01-01
      • 2020-10-10
      • 2018-04-10
      • 1970-01-01
      相关资源
      最近更新 更多