在Python脚本中,如何检查MySQL字段中存储的日期时间字符串,而无需秒精度?
我已经创建了一个基于systemd服务的调度器,该服务由计时器触发。Python脚本每分钟触发一次,并执行以下任务:在Python脚本中,如何检查MySQL字段中存储的日期时间字符串,而无需秒精度?,python,mysql,datetime,Python,Mysql,Datetime,我已经创建了一个基于systemd服务的调度器,该服务由计时器触发。Python脚本每分钟触发一次,并执行以下任务: 连接到数据库选择所有活动计划 检查“执行日期”字段现在是否为 如果时机合适,触发一个动作 似乎我对“now”和从数据库检索的DateTime字段值之间的比较不正常。事实上,DateTime在数据库字段中以秒存储,但我不需要秒精度,我只需要检查“现在”年、月、日、小时和分钟 例如: MySQL表 +----+--------+---------+------------------
+----+--------+---------+-----------------------+
| id | status | type | execution_date |
+----+------------------+-----------------------+
| 1 | X | foo | 2021-02-10 07:20:00 |
+----+------------------+-----------------------+
| 2 | Y | bar | 2021-02-10 08:23:00 |
+----+--------+---------+-----------------------+
Python脚本
import datetime
import mysql.connector
from mysql.connector.cursor import MySQLCursor
from mysql.connector import Error
def date_is_now(date_str):
date_current = datetime.datetime.now()
date_compare = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M")
if date_current == date_compare:
return True
else:
return False
connect = mysql.connector.connect(user='db_user', password='password',host='XX.XX.XX.XX',database='db')
query = "SELECT * FROM schedule_table WHERE status = 'X'"
cursor = connect.cursor(dictionary=True)
cursor.execute(query)
result = cursor.fetchall()
logger.debug("{} schedules are active".format(len(result)))
for schedule in result:
if schedule['type'] == 'foo' and date_is_now(schedule['execution_date']):
logger.info("Schedule action is being triggered")
import datetime
import mysql.connector
from mysql.connector.cursor import MySQLCursor
from mysql.connector import Error
def date_is_now(date_arg):
# See change above
date_current = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
date_compare = date_arg.strftime("%Y-%m-%d %H:%M")
if date_current == date_compare:
return True
else:
return False
connect = mysql.connector.connect(user='db_user', password='password',host='XX.XX.XX.XX',database='db')
query = "SELECT * FROM schedule_table WHERE status = 'X'"
cursor = connect.cursor(dictionary=True)
cursor.execute(query)
result = cursor.fetchall()
logger.debug("{} schedules are active".format(len(result)))
for schedule in result:
if schedule['type'] == 'foo' and date_is_now(schedule['execution_date']):
logger.info("Schedule action is being triggered")
如何在没有秒精度的情况下比较now和数据库中存储的日期?比较日期时间的标准模式是进行范围比较,而不是相等比较 要检查执行日期是否与NOW()在同一分钟内,我们可以使用表达式派生范围的开始和结束 考虑:
SELECT NOW()
, DATE_FORMAT( NOW() ,'%Y-%m-%d %H:%m') + INTERVAL 0 MINUTE AS _range_start
, DATE_FORMAT( NOW() ,'%Y-%m-%d %H:%m') + INTERVAL 1 MINUTE AS _range_end
我们可以在WHERE子句中使用表达式来与bare datetime列进行比较:
SELECT t.execution_date
, ...
FROM mytable t
WHERE t.execution_date >= DATE_FORMAT( NOW() ,'%Y-%m-%d %H:%m') + INTERVAL 0 MINUTE
AND t.execution_date < DATE_FORMAT( NOW() ,'%Y-%m-%d %H:%m') + INTERVAL 1 MINUTE
ORDER
BY t.execution_date
选择t.execution\u日期
, ...
来自MyT表
其中t.execution\u date>=日期格式(现在(),“%Y-%m-%d%H:%m”)+间隔0分钟
和t.execution_date
如果我们不想筛选行,而是返回行并只是“标记”哪些行属于日期时间范围,我们可以使用选择列表中的表达式
SELECT t.execution_date
, CASE
WHEN t.execution_date >= DATE_FORMAT( NOW() ,'%Y-%m-%d %H:%m') + INTERVAL 0 MINUTE
AND t.execution_date < DATE_FORMAT( NOW() ,'%Y-%m-%d %H:%m') + INTERVAL 1 MINUTE
THEN TRUE
ELSE FALSE
END AS is_now
, ...
FROM mytable t
WHERE ...
ORDER BY ...
选择t.execution\u日期
案例
当t.execution\u date>=日期格式(现在(),“%Y-%m-%d%H:%m”)+间隔0分钟
和t.execution_date
注意:我们现在不必使用database()。我们可以提供一个值(格式正确)来代替NOW()。一个快速的解决方案可能是将datetime转换为字符串并检查是否相等(见下文)。如前所述,这可能不是关于日期范例的最干净的解决方案 Python脚本
import datetime
import mysql.connector
from mysql.connector.cursor import MySQLCursor
from mysql.connector import Error
def date_is_now(date_str):
date_current = datetime.datetime.now()
date_compare = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M")
if date_current == date_compare:
return True
else:
return False
connect = mysql.connector.connect(user='db_user', password='password',host='XX.XX.XX.XX',database='db')
query = "SELECT * FROM schedule_table WHERE status = 'X'"
cursor = connect.cursor(dictionary=True)
cursor.execute(query)
result = cursor.fetchall()
logger.debug("{} schedules are active".format(len(result)))
for schedule in result:
if schedule['type'] == 'foo' and date_is_now(schedule['execution_date']):
logger.info("Schedule action is being triggered")
import datetime
import mysql.connector
from mysql.connector.cursor import MySQLCursor
from mysql.connector import Error
def date_is_now(date_arg):
# See change above
date_current = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
date_compare = date_arg.strftime("%Y-%m-%d %H:%M")
if date_current == date_compare:
return True
else:
return False
connect = mysql.connector.connect(user='db_user', password='password',host='XX.XX.XX.XX',database='db')
query = "SELECT * FROM schedule_table WHERE status = 'X'"
cursor = connect.cursor(dictionary=True)
cursor.execute(query)
result = cursor.fetchall()
logger.debug("{} schedules are active".format(len(result)))
for schedule in result:
if schedule['type'] == 'foo' and date_is_now(schedule['execution_date']):
logger.info("Schedule action is being triggered")
使用此代码:
import datetime
import mysql.connector
from mysql.connector.cursor import MySQLCursor
from mysql.connector import Error
def date_is_now(date_str):
date_current = datetime.datetime.now()
date_compare = datetime.datetime.strptime(date_str, "%Y-%m-%d %H:%M")
if date_current == date_compare:
return True
else:
return False
connect = mysql.connector.connect(user='db_user', password='password',host='XX.XX.XX.XX',database='db')
query = "SELECT * FROM schedule_table WHERE status = 'X'"
cursor = connect.cursor(dictionary=True)
cursor.execute(query)
result = cursor.fetchall()
logger.debug("{} schedules are active".format(len(result)))
for schedule in result:
dt = schedule['execution'].strftime("%Y-%m-%d %H:%M:%S").split(':')
dt[2] = '00'
execution_date_formatted = dt[0] + ':' + dt[1] + ':' + dt[2]
if schedule['type'] == 'foo' and date_is_now(execution_date_formatted):
logger.info("Schedule action is being triggered")
我让程序用日期编辑
str
,这样它就可以用00
替换秒中的任何数字。在您提到的一条评论中,Python会自动将str
转换为datetime
对象。您可以使用此功能将秒数替换为00
:
schedule['execution'].replace(秒=0)
replace()
的参数是:
年份
月份
day
hour
分钟
second
微秒
08:15
是=08:15:00.000
和<08:16:00.000
,另一个例子是,对于日期时间“2021年2月”,“2021-02-01和1dt2021-03-01”。如果要进行相等比较,则需要对这两个值进行截断、格式化,以使它们具有相等的精度。我个人的偏好是让精度保持不变,范围比较是关于Python实现的,而不是SQL@donmelchior:问题被标记为“mysql”;题为“MySQL字段”;这个答案说明了问题评论中建议的“范围比较”模式。实现你需要的一切。此答案旨在说明datetime范围比较的实现。(就我个人而言,我不会从数据库中提取我知道不需要的行。客户端上的“选择所有行”然后过滤适用于小集合,但该模式不可扩展。)我对这个问题的评论适用于Python。。。使用范围比较代替相等比较。从数据库检索的schedule['execution']自动转换为Python datetime,并且不是字符串。我更正了代码。它将datetime
对象转换为字符串,对其进行处理,然后以00
代替秒将其打印为字符串:2021-02-10 07:21:00
。