📜  更新 sqlaclehmy sqlalchemy.orm.evaluator.UnevaluatableError:无法使用运算符评估 BinaryExpression<function like_op at 0x03CF1DF0> - SQL (1)

📅  最后修改于: 2023-12-03 15:26:23.088000             🧑  作者: Mango

SQLAlchemy 中的 UnevaluatableError 异常

介绍

在使用 SQLAlchemy ORM 进行查询时,有时会遇到 UnevaluatableError 异常,它是由 sqlalchemy.orm.evaluator.evaluate_binop 函数抛出的,表示无法对一个二元表达式进行求值。常见的情形包括:

  • 在 query 中使用了不支持的操作符
  • 试图对 NULL 值进行比较或操作
  • 在 query 中使用了 Python 中不支持的操作符,如 ^
解决方法
  • 检查 query 中使用的操作符是否被支持。例如,使用 model.filter(column.like(pattern)) 来实现字符串模糊匹配,而不是直接使用 column.ilike(pattern),因为 ilike 操作符不支持某些数据库。
  • 使用 IS NULL 或 IS NOT NULL 来对 NULL 值进行比较。例如,使用 model.filter(column == None) 会导致 UnevaluatableError,应该使用 model.filter(column.is_(None))
  • 避免在 query 中使用 Python 中不支持的操作符。例如,使用 | 替代 ^ 来进行位运算。
示例代码
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy import or_
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm.evaluator import UnevaluatableError
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    
    id = Column(Integer, primary_key=True)
    name = Column(String)
    
# 创建数据库连接和会话
engine = create_engine('sqlite:///test.db')
Session = sessionmaker(bind=engine)
session = Session()

# 示例一:使用不支持的操作符
try:
    session.query(User).filter(User.name ^ 'jane').all()
except UnevaluatableError as e:
    print(f"UnevaluatableError: {e}")
# 输出:UnevaluatableError: Cannot evaluate BinaryExpression with operator <operator xorm={operator}> and types {type(arg1)}, {type(arg2)}

# 示例二:比较 NULL 值
try:
    session.query(User).filter(User.name == None).all()
except UnevaluatableError as e:
    print(f"UnevaluatableError: {e}")
# 输出:UnevaluatableError: Cannot evaluate BinaryExpression with operator '==/IS NOT DISTINCT FROM' and types <class 'sqlalchemy.orm.attributes.InstrumentedAttribute'>, <class 'NoneType'>

# 使用 IS NULL 来比较 NULL 值
session.query(User).filter(User.name.is_(None)).all()

# 示例三:使用字符串模糊匹配
try:
    session.query(User).filter(User.name.ilike('jan%')).all()
except UnevaluatableError as e:
    print(f"UnevaluatableError: {e}")
# 输出:UnevaluatableError: Cannot evaluate BinaryExpression with operator 'like/ILIKE' and types <class 'sqlalchemy.orm.attributes.InstrumentedAttribute'>, <class 'str'>

# 使用 like 操作符来进行字符串模糊匹配
session.query(User).filter(User.name.like('jan%')).all()

以上是对于 UnevaluatableError 异常的介绍和解决方法,希望能够帮助使用 SQLAlchemy ORM 的开发者排除相关问题。