sqlalchemy表达式不是_

时间:2014-08-05 13:41:40

标签: python sqlalchemy

我有以下代码:

 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'))

我仍然得到相同的输出。

提前致谢!

1 个答案:

答案 0 :(得分:3)

SQL中的

NULL与Python中的None行为不同,而SQLAlchemy通常不会改变它。 SQL表达式NULL != 'delete'的结果是NULL,而不是TRUE。在WHERE子句中,NULL被视为false。

要将表达式中的NULL转换为TRUEFALSE,您可以使用IS表达式。在您的示例中,如果TRUE"Action"不同,您希望返回'delete',即使它为空:

("Action" != 'delete') IS NOT FALSE

如果括号内的表达式为FALSE,则整个表达式为FALSE。如果是TRUENULL,则整个表达式为TRUE

要在SQLAlchemy中创建此表达式,请使用isnot()

(user.c.Action != 'delete').isnot(False)

如果我们重写这个以删除双重否定,我会更容易理解:

(user.c.Action == 'delete').isnot(True)

应该生成SQL:

("Action" = 'delete') IS NOT TRUE