0

我有一个 Sqlite3 表,其中有一LastUpdated列包含格式为 UTC 的日期时间"2013-12-24 07:11:21",并且该表中的所有行都在 2 天前更新。

我想写一个SELECT语句来只返回一段时间没有更新的行:

SELECT LastUpdated FROM UserToken WHERE DATETIME(LastUpdated) < DATETIME('now', '-4 days');

我正在尝试使用 sqlite3 标准库从 Python 运行此查询,并且我希望过时的时间段是可变的。为了安全起见,我尝试使用sqlite3 标准库文档中提到的参数替换来使用变量stale_delta_parameter

dbcursor.execute("SELECT LastUpdated FROM UserToken WHERE TokenValid = 1 AND DATETIME(LastUpdated) < DATETIME('now', ?)", (stale_delta_parameter,))

我第一次运行它时,我设置stale_delta_parameter = '-4 days'并正确返回零行。然后我将值更改stale_delta_parameter为“-1 天”并运行查询。查询继续返回 0 行,而不是所有行的预期结果。

当我重新启动计算机时,查询似乎第一次运行良好,但同样,如果我使用一个 delta 值运行 python 脚本,一旦我更改了 delta 值,结果将继续是第一个实例的值运行查询。此外,如果我编写两个 SELECT 语句,其中设置了 query1'-4 days'应该不返回任何行,而 query2'-1 days'应该返回所有行,然后在运行脚本一次之后,我切换这些查询的值,查询的输出不会转变。

我认为这可能是不正确的 sql 查询,所以我尝试对 delta 进行硬编码并在 Sqlite3 shell 中运行查询。每次都按我的预期工作,所以查询没有错。

然后我尝试将变量stale_delta_parameter从扩展'-n days'DATETIME('now', '-n days')以防万一参数替换在 Sqlite 的特殊DATETIME()函数中无法正常工作。奇怪的行为没有改变。

在 Sqlite3 标准库或 Python DB-API 中是否发生了某种缓存,可能会阻止更新传递给底层数据库的查询?

我在文档中找不到任何东西,但这是我能想出的唯一符合这种行为的理论。

我试图找到一种方法来打印从 Python 传递给数据库的组装查询,因此我可以验证数据库没有获得查询的更新版本,但我找不到任何类型的打印方法的组装查询dbcursor.execute(...)

这是实际的代码:

til_user_tokens_go_stale = '4 days'
stale_delta_parameter = "DATETIME('now','-%s')" % til_user_tokens_go_stale  
dbcursor.execute('''
                 SELECT UserToken, UserID, AppID 
                 FROM UserToken 
                 WHERE TokenValid = 1 AND DATETIME(LastUpdated) < ?
                 ''', (stale_delta_parameter,))
all_tokens = dbcursor.fetchall()
print len(all_tokens) # For debugging, shows me how many rows are returned
4

1 回答 1

1

从 SQLite文档

“变量”或“参数”标记指定表达式中的占位符,用于在运行时使用 sqlite3_bind() 系列 C/C++ 接口填充的值。

这些接口包括基本类型(字符串、数字、blob),但不包括datetime.

完成您所追求的一种方法是在unixepochor juliandays 中提供偏移量,然后重新格式化查询以进行算术减法。

但是,您展示的第一个参数化版本应该可以工作;它在 Lua 中:

> db = sqlite3.open(':memory:')
> db:execute'create table t (d);'
> db:execute"insert into t values ('2013-12-26 14:20:00');"
> st = db:prepare "select * from t where d < datetime('now',?);"
> st:bind(1,'+1 day');
> for row in st:urows() do print (row) end
2013-12-26 14:20:00
> st:bind(1,'-1 day');
> for row in st:urows() do print (row) end
> 
于 2013-12-26T19:12:54.610 回答