我有以下代码:
s = select([user.c.Title]).where(user.c.Action != 'delete')
conn = engine.connect()
rows = conn.execute(s).fetchall()
print rows
conn.close()
代码应该获取“Action”列不相等的标题列表 '删除'。每次我运行代码时,我都会返回一个空列表。 控制台中echo设置为True的输出为:
2014-08-05 16:27:31,492 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1
2014-08-05 16:27:31,492 INFO sqlalchemy.engine.base.Engine ()
2014-08-05 16:27:31,492 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1
2014-08-05 16:27:31,492 INFO sqlalchemy.engine.base.Engine ()
2014-08-05 16:27:31,493 INFO sqlalchemy.engine.base.Engine SELECT "Notes"."Title"
FROM "Notes"
WHERE "Notes"."Action" != ?
2014-08-05 16:27:31,493 INFO sqlalchemy.engine.base.Engine ('delete',)
[]
我检查了数据库,并且存在没有'删除'的行 '行动'专栏。
当我使用时:
s = select([user.c.Title]).where(not_(user.c.Action != 'delete'))
我仍然得到相同的输出。
提前致谢!
答案 0 :(得分:3)
NULL
与Python中的None
行为不同,而SQLAlchemy通常不会改变它。 SQL表达式NULL != 'delete'
的结果是NULL
,而不是TRUE
。在WHERE
子句中,NULL
被视为false。
要将表达式中的NULL
转换为TRUE
或FALSE
,您可以使用IS
表达式。在您的示例中,如果TRUE
与"Action"
不同,您希望返回'delete'
,即使它为空:
("Action" != 'delete') IS NOT FALSE
如果括号内的表达式为FALSE
,则整个表达式为FALSE
。如果是TRUE
或NULL
,则整个表达式为TRUE
。
要在SQLAlchemy中创建此表达式,请使用isnot()
:
(user.c.Action != 'delete').isnot(False)
如果我们重写这个以删除双重否定,我会更容易理解:
(user.c.Action == 'delete').isnot(True)
应该生成SQL:
("Action" = 'delete') IS NOT TRUE