SQLAlchemy:运算符 LIKE 和自定义类型
SQLAlchemy: operator LIKE and custom types
我使用 sqlalchemy ORM。我有以下自定义列类型和 table-映射 class:
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 跟踪中我看到
...WHERE description LIKE '"%some pattern%"'
而不是
...WHERE description LIKE '%some pattern%'
所以没有匹配的行。
如何按照我想要的方式使用 LIKE
运算符执行查询?
可以使用 literal()
:
绕过自动类型处理(或使用 type_
参数强制你自己处理)
Task.description.like(literal("%some pattern%"))
另一种方法是在尝试使用像 like
这样的运算符之前,使用 cast()
或 type_coerce()
将列强制 为文本形式, contains
或其他:
from sqlalchemy import type_coerce, String
stmt = select([my_table]).where(
type_coerce(my_table.c.json_data, String).like('%foo%'))
或者您可以在自定义类型 class 定义中执行此操作:
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
我使用 sqlalchemy ORM。我有以下自定义列类型和 table-映射 class:
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 跟踪中我看到
...WHERE description LIKE '"%some pattern%"'
而不是
...WHERE description LIKE '%some pattern%'
所以没有匹配的行。
如何按照我想要的方式使用 LIKE
运算符执行查询?
可以使用 literal()
:
type_
参数强制你自己处理)
Task.description.like(literal("%some pattern%"))
另一种方法是在尝试使用像 like
这样的运算符之前,使用 cast()
或 type_coerce()
将列强制 为文本形式, contains
或其他:
from sqlalchemy import type_coerce, String
stmt = select([my_table]).where(
type_coerce(my_table.c.json_data, String).like('%foo%'))
或者您可以在自定义类型 class 定义中执行此操作:
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