sqlalchemy 表达式 not_
我有以下代码:
s = select([user.c.Title]).where(user.c.Action != 'delete')
conn = engine.connect()
rows = conn.execute(s).fetchall()
print rows
conn.close()
这段代码的目的是从数据库中获取一个标题列表,条件是'Action'这一列的值不能是'delete'。但是每次我运行这段代码,得到的结果都是一个空列表。
当我在控制台中把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',)
[]
我检查过数据库,确实有一些行的'Action'列中没有'delete'这个值。
当我使用:
s = select([user.c.Title]).where(not_(user.c.Action != 'delete'))
我仍然得到相同的输出。
提前谢谢你们!
1 个回答
4
在SQL中,NULL
的表现和Python中的None
是不一样的,SQLAlchemy也没有改变这一点。比如,SQL表达式NULL != 'delete'
的结果是NULL
,而不是TRUE
。在WHERE
条件中,NULL
被当作假来处理。
如果你想把表达式中的NULL
转换成TRUE
或FALSE
,可以使用IS
表达式。在你的例子中,你希望在"Action"
和'delete'
不相等时返回TRUE
,即使它是NULL
也一样:
("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