为什么 MYSQL DB 在对 Django models.DateTimeField 求平均值时返回损坏的值?

2024-04-26

我正在 MySQL(实际上是 MariaDB)数据库上运行 Django 应用程序。

我的 Django 模型如下所示:

from django.db import models
from django.db.models import Avg, Max, Min, Count

class myModel(models.Model):
    my_string = models.CharField(max_length=32,)
    my_date = models.DateTimeField()

    @staticmethod
    def get_stats():            
        logger.info(myModel.objects.values('my_string').annotate(
                count=Count("my_string"), 
                min=Min('my_date'), 
                max=Max('my_date'), 
                avg=Avg('my_date'),
            )
        )

当我跑步时get_stats(),我得到以下日志行:

[2015-06-21 09:45:40] INFO [all_logs:96] [{'my_string': u'A', 'count': 2, 'avg': 20080507582679.5, 'min': datetime.datetime(2007, 8, 2, 11, 33, 53, tzinfo=<UTC>), 'max': datetime.datetime(2009, 2, 13, 5, 20, 6, tzinfo=<UTC>)}]

我遇到的问题是数据库返回的 my_date 字段的平均值是:20080507582679.5。仔细看看那个数字。这是无效的日期格式。

为什么数据库不返回这两个日期的平均值的有效值?如果所描述的方法失败,我如何获得该字段的实际平均值? Django DateTimeField 是否未设置为处理平均值?


Q1:为什么数据库没有返回这两个日期的平均值的有效值?

A:返回的值是预期的,它是明确定义的 MySQL 行为。

MySQL 自动将日期或时间值转换为number如果该值用于数字上下文反之亦然。

MySQL参考手册:https://dev.mysql.com/doc/refman/5.5/en/date-and-time-types.html https://dev.mysql.com/doc/refman/5.5/en/date-and-time-types.html


在 MySQL 中,AVG聚合函数运行于numeric values.

在 MySQL 中,一个DATE or DATETIME表达式可以在a中求值numeric语境。

作为一个简单的演示,执行numeric对 a 进行加法运算DATETIME将日期时间值隐式转换为数字。这个查询:

  SELECT NOW(), NOW()+0

返回如下结果:

  NOW()                                NOW()+0  
  -------------------  -----------------------
  2015-06-23 17:57:48    20150623175748.000000

请注意,表达式的返回值NOW()+0 is not a DATETIME, 它是number.

当您指定一个SUM() or AVG()函数在一个DATETIME表达式,相当于转换DATETIME化为一个数,然后求和 或对数字进行平均。

也就是说,这个表达式的返回AVG(mydatetimecol)等价于该表达式的返回:AVG(mydatetimecol+0)

被“平均”的是一个数值。您已经观察到,返回的值不是有效的日期时间;即使它碰巧看起来像有效的日期时间,它也可能不是您认为真正的“平均值”的值。


Q2:如果上述方式失败,如何得到该字段的实际平均值?

A2:一种方法是将日期时间转换为可以“准确”平均的数值,然后将其转换回日期时间。

例如,您可以将日期时间转换为表示秒数从某个固定的时间点开始,例如

  TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)

然后,您可以对这些值进行“平均”,以获得平均值秒数从某个固定的时间点开始。 (注意:要注意加起来的行数极多,数值极大,超过限制(最大数值),数值溢出问题。)

  AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date))

要将其转换回日期时间,请将该值添加为秒数回到固定时间点:

  '2015-01-01' + INTERVAL AVG(TIMESTAMPDIFF(SECOND,'2015-01-01',t.my_date)) SECOND

(请注意,DATEIME值在 MySQL 会话的时区中进行评估;所以存在边缘情况,其中的设置time_zoneMySQL会话中的变量会对返回值产生一些影响。)

MySQL还提供了一个UNIX_TIMESTAMP()函数返回一个 Unix 风格的整数值,即从纪元开始(UTC 时间 1970 年 1 月 1 日午夜)起的秒数。您可以使用它来更简洁地完成相同的操作:

  FROM_UNIXTIME(AVG(UNIX_TIMESTAMP(t.my_date)))

请注意,这个最终表达式实际上在做同样的事情...将日期时间值转换为自 '1970-01-01 00:00:00' UTC 以来的秒数,取其数值平均值,然后添加该平均值返回到 '1970-01-01' UTC 的秒数,最后将其转换回DATETIME值,在当前会话中表示time_zone.


Q3:Django DateTimeField 没有设置来处理平均吗?

A:显然,Django 的作者对 SQL 表达式从数据库返回的值感到满意AVG(datetime).

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 MYSQL DB 在对 Django models.DateTimeField 求平均值时返回损坏的值? 的相关文章

  • python 2.7 字符 \u2013 [重复]

    这个问题在这里已经有答案了 我有以下代码 coding utf 8 print u William Burges 1827 81 was an English architect and designer 当我尝试从cmd运行它时 我收到以
  • 如何使用 django-haystack 和 elasticsearch 后端进行模糊搜索?

    看起来好像elasticsearch支持模糊查询 http www elasticsearch org guide reference query dsl fuzzy query http www elasticsearch org gui
  • Redis SYNC 套接字上的错误情况:连接被拒绝

    在我的 django 应用程序中使用 celery 和 redis 一切都工作正常 直到我遇到了问题 redis 文件的位置已更改 redis 无法访问它们 经过查找 原来这是由于网络随机攻击造成的 需要添加confg 我添加文件后 一段时
  • 将numpy字符串数组转换为int数组[重复]

    这个问题在这里已经有答案了 我有一个 numpy ndarray a 0 99 0 56 0 56 2 02 0 96 如何将其转换为int 输出 a 0 99 0 0 0 56 0 56 2 02 0 96 我想要 0 0 代替空白 im
  • Python 中意外的缩进错误[重复]

    这个问题在这里已经有答案了 我有一段简单的代码 我不明白我的错误来自哪里 解析器在第 5 行 if 语句 上用意外的缩进向我咆哮 有人看到这里的问题吗 我不 def gen fibs a b 0 1 while True a b b a b
  • tf.keras.utils.image_dataset_from_directory,但标签来自 csv?

    请告诉我哪里出错了 我正在研究 Kaggle 狗品种分类挑战 我想尝试 one hot 编码与标签编码 图像未在图像目录中拆分 因此我无法将 推断 与 tf keras utils image dataset from directory
  • 使用光栅重新投影 .tiff 文件:CRSError:无法解析 WKT。 OGR 错误代码 6

    我正在尝试使用以下代码将 tiff 文件重新投影到 EPSG 32638 我安装过的版本 光栅版本 1 1 5 Numpy 版本 1 18 1 这是我正在使用的代码 https rasterio readthedocs io en late
  • 在Python中修改大型文本文件最后一行的最有效方法

    我需要更新几个超过 2GB 的文件的最后一行 这些文件由无法读取的文本行组成readlines 目前 它可以通过逐行循环来正常工作 但是 我想知道是否有任何编译库可以更有效地实现这一点 谢谢 目前的方法 myfile open large
  • 使用 PyQt4 在 QWidget 上进行 eventFilter

    我有一个 QMainWindow 其中包含DrawingPointsWidget 该小部件随机绘制红点 我通过使用以下命令为 MouseHovering 事件安装事件过滤器 在 QMainWindow 的状态栏中显示鼠标坐标self ins
  • 有效地减去不同形状的 numpy 数组

    使用 numpy 出色的广播规则 您可以减去形状 3 数组v来自形状 5 3 数组X with X v 结果是一个形状 5 3 数组 其中每一行i是有区别的X i v 有没有办法减去形状 n 3 数组w from X使得每一行w从整个数组中
  • 计算两个表中等效行的交集

    我有两个 FITS 文件 让我们考虑一下例如第一个文件有 100 行和 2 列 第二个文件有 1000 行和 2 列 FITS FILE 1 FITS FILE 2 A B C D 1 2 1 2 1 3 1 2 2 4 1 2 我需要采取
  • dataframe KeyError,尽管它存在

    鉴于数据 rows x 1 y 2 z 3 x 2 y 2 z 3 如果我尝试构建这样的数据框 frame pd DataFrame from records rows index x 效果很好 然而 这 frame pd DataFram
  • 如何将填充轮廓投影到 3D 曲面图上

    我只是想在 3D 中绘制一个表面及其轮廓 就像this http matplotlib org examples mplot3d contourf3d demo2 html例子 这是我用来执行此操作的代码 import matplotlib
  • Spring JPA (Hibernate) Entity Manager 何时将连接返回到连接池?

    在我的 java 进程中 我使用以下 spring 配置连接到 MySql Configuration EnableTransactionManagement PropertySources PropertySource classpath
  • Pytest - 如何将参数传递给 setup_class?

    我有一些代码 如下所示 我得到了too few args当我运行它时出错 我没有打电话setup class明确地 所以不确定如何向它传递任何参数 我尝试用以下方法装饰该方法 classmethod 但仍然看到相同的错误 我看到的错误是这样
  • tweepy 计数限制为 200?

    我目前正在尝试检索一些拥有大量关注者的大帐户的关注者 我正在使用 Tweepy 和这段代码 带光标 follower cursors tweepy Cursor api followers id id var count 5000 for
  • 如何使用电子表格中的第一行作为 Dataframe 列名称而不是 0 1 2...等?

    我希望我的数据框将第一行名称显示为数据框列名称 而不是从 0 等编号 我该如何执行此操作 我尝试使用 pandas 和 openpyxl 模块将我的 Excel 电子表格转换为数据框 import pandas as pd from ope
  • Django - 在启动时执行代码

    我正在使用 Django 1 9 3 我有一个包含多个应用程序的项目 我想在项目启动时更新其中一个应用程序的表 用例 例如 假设我想在我的网站上销售商品 我有一个包含模型项目的应用程序 我在 Django 之外有一个网络服务 它提供服务 g
  • Seaborn 分组条形图,使用总值而不是平均值

    我有一个关于如何组织数据以使用 seaborn 制作条形图的问题 我的数据输入如下所示 influencer platform reach person a instagram 10000 person b instagram 5000 p
  • 将下载的字体添加到 Tkinter

    我想下载一个开源字体并在我的 Python Tkinter 程序中使用它 如何告诉 Tkinter 从目录导入字体或将字体放在与程序相同的文件夹中 Note 我已经寻找答案一段时间了 甚至阅读了 Tkinter 的 API 参考 了解我能找

随机推荐