Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用SQLAlchemy过滤彼此相隔两秒钟的对象_Python_Database_Datetime_Sqlalchemy - Fatal编程技术网

Python 使用SQLAlchemy过滤彼此相隔两秒钟的对象

Python 使用SQLAlchemy过滤彼此相隔两秒钟的对象,python,database,datetime,sqlalchemy,Python,Database,Datetime,Sqlalchemy,我有两个表,列为“date”。一个保持(名称、日期),另一个保持(日期、p1、p2)。给定一个名称,我想使用表1中的日期从表2中查询p1和p2;如果表1中的日期在表2中日期的两秒内,则应进行匹配 如何使用SQLAlchemy实现这一点 我已尝试(未成功)使用between运算符和一个类似以下的子句: td = datetime.timedelta(seconds=2) q = session.query(table1, table2).filter(table1.name=='my_name')

我有两个表,列为“date”。一个保持(名称、日期),另一个保持(日期、p1、p2)。给定一个名称,我想使用表1中的日期从表2中查询p1和p2;如果表1中的日期在表2中日期的两秒内,则应进行匹配

如何使用SQLAlchemy实现这一点

我已尝试(未成功)使用
between
运算符和一个类似以下的子句:

td = datetime.timedelta(seconds=2)
q = session.query(table1, table2).filter(table1.name=='my_name').\
    filter(between(table1.date, table2.date - td, table2.date + td))
有什么想法吗

编辑: 我通过以下方法解决了这个问题:

from sqlalchemy.sql import between
import datetime
# [all other relevant imports]

td = datetime.timedelta(seconds=2)
t1_entry = session.query(table_1).filter(table_1.name == 'the_name').first()
if t1_entry is not None:
 tmin = t1_entry.date - td
 tmax = t1_entry.date + td
 t2_entry = session.query(table_2).filter(between(table_2.date, tmin, tmax)).first()
 return (t1_entry, t2_entry)
return None

因此可以进行比较,但我不确定该方法是否有效。

首先让我解释一下为什么您尝试的方法无效。SQLAlchemy只是编写SQL查询的一种方便方法,尽管如此,所有查询都发生在远程端。SQLAlchemy列是一些特殊对象,它们的
\uuuuueq\uuuuuuuuu
\uuugt\uuuuuuuuu
等方法会被覆盖,以返回的不是
True
False
,而是其他特殊对象,它们会记住与它们进行比较的对象是什么,并且可以在以后生成适当的SQL语句。添加etc也是如此:自定义的
\uuuuu add\uuuuu
\uuuu sub\uuuu
方法不返回数字或串联字符串,但也返回生成sql语句的对象。您可以将它们与字符串、整数等、其他列、select语句、mysql函数调用等进行比较/添加,但不能与特殊的python对象(如TimeDelta)进行比较/添加。(简化,技术上可能不是100%正确;)

因此,您可以做的是:

  • 将数据库中的值设为整数,例如unix时间戳。这样,您的
    between
    查询将起作用(使用
    2
    而不是delta)
  • 使用数据库端函数将日期时间格式日期转换为unix时间戳,然后进行比较
更新:我对它做了一些研究,不知怎么的,它确实有效,甚至有一种数据类型。但是,至少在这里它不能正常工作:

MySQL:

>>> db.session.execute(db.select([User.date_joined, User.date_joined + timedelta(seconds=2)], limit=1)).fetchall()
[(datetime.datetime(2009, 7, 10, 20, 47, 33), 20090710204733.0)]
>>> db.session.execute(db.select([User.date_joined, User.date_joined + 2], limit=1)).fetchall()
[(datetime.datetime(2009, 7, 10, 20, 47, 33), 20090710204735.0)]
>>> db.session.execute(db.select([User.date_joined+0, User.date_joined + 2], limit=1)).fetchall()
[(20090710204733.0, 20090710204735.0)]
SQLite:

>>> db.session.execute(db.select([User.date_joined, User.date_joined + timedelta(seconds=2)], limit=1)).fetchall()
TypeError: expected string or buffer
>>> db.session.execute(db.select([User.date_joined, User.date_joined + 2], limit=1)).fetchall()
[(datetime.datetime(2010, 5, 28, 23, 8, 22, 476708), 2012)]
>>> db.session.execute(db.select([User.date_joined+0, User.date_joined + 2], limit=1)).fetchall()
[(2010, 2012)]
我不知道为什么第一个在MySQL上失败,为什么它返回float。SQLite错误似乎是因为SQLite而发生的


你必须稍微考虑一下,也许你会找到一种有效的方法——但我认为要保持真正的dbms独立性,整数方法将是唯一可行的方法。

经过一段时间的讨论,这个问题仍然悬而未决,到目前为止,我提出的方法是:

from sqlalchemy.sql import between
import datetime
# [all other relevant imports]

td = datetime.timedelta(seconds=2)
t1_entry = session.query(table_1).filter(table_1.name == 'the_name').first()
if t1_entry is not None:
 tmin = t1_entry.date - td
 tmax = t1_entry.date + td
 t2_entry = session.query(table_2).filter(between(table_2.date, tmin, tmax)).first()
 return (t1_entry, t2_entry)
return None

如果您有更好的想法,我将接受您的答案。

方法是将日期转换为unix时间戳

在最近的一段代码中,我成功地使用了以下几行:

from sqlalchemy.sql import func
...
q = q.join(q2, func.abs(func.unix_timestamp(rssi1.datetime)-func.unix_timestamp(q2.c.datetime)) <=2 )
来自sqlalchemy.sql导入函数
...

q=q.join(q2,func.abs(func.unix_timestamp(rssi1.datetime)-func.unix_timestamp(q2.c.datetime))时间对象的不同格式可能会成为一个令人头痛的问题!