python - Django 1.11 - 如何确保 TruncYear 生成 Zulu 时间

标签 python django postgresql datetime django-1.11

我使用的是 Django 1.11 和 Postgres 9.4。

如何确保 TruncYear 生成祖鲁时间 (2019-10-01T00:00:00Z)。我注意到它创建带有时区的日期时间,如下所示 (2017-01-01T00:00:00+03:00)

这是我的 TruncYear 查询集代码:

from django.db.models import Count
from django.db.models.functions import TruncMonth, TruncYear, TruncDay, TruncHour

tracking_in_timeseries_data = Tracking.objects.annotate(
         year=TruncYear('created_at')).values('year', 'venue').annotate(
         count=Count('employee_id', distinct = True)).order_by('year') 

>>> for exp in tracking_in_timeseries_data:
...     print(exp['year'], exp['venue'], exp['count'])

2017-01-01 00:00:00+00:00 4 1
2019-01-01 00:00:00+00:00 2 2
2019-01-01 00:00:00+00:00 3 1
2019-01-01 00:00:00+00:00 4 1
2019-01-01 00:00:00+00:00 5 1
2019-01-01 00:00:00+00:00 6 1


>>> tracking_in_timeseries_data
<QuerySet [{'venue': 4, 'year': datetime.datetime(2017, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 2, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 2}, {'venue': 3, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 4, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 5, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}, {'venue': 6, 'year': datetime.datetime(2019, 1, 1, 0, 0, tzinfo=<UTC>), 'count': 1}]>

如果我序列化它会产生这样的结果:

序列化器.py

class TimeseriesYearSerializer(serializers.ModelSerializer):
    venue = VenueTSSerializer(read_only=True)
    year = serializers.DateTimeField(read_only=True)
    count = serializers.IntegerField(read_only=True)

    class Meta:
        model = Tracking
        fields = ['venue', 'year', 'count']

输出:

[
    {
      "count": 1,
      "year": "2017-01-01T00:00:00+03:00",
      "venue_id": 2
    },
    {
      "count": 1,
      "year": "2018-01-01T00:00:00+03:00",
      "venue_id": 1
    },
    {
      "count": 1,
      "year": "2018-01-01T00:00:00+03:00",
      "venue_id": 2
    },
    {
      "count": 3,
      "year": "2019-01-01T00:00:00+03:00",
      "venue_id": 1
    },
    {
      "count": 3,
      "year": "2019-01-01T00:00:00+03:00",
      "venue_id": 2
    }
  ]

如何确保 TruncYear 查询集生成祖鲁时间的日期时间字符串,如 2019-10-01T00:00:00Z,而不是时区 2019-01-01T00:00:00+03:00。

更新: 我注意到我通过重新启动 django 服务临时修复了这个问题。

sudo supervisorctl stop all
sudo supervisorctl start all

然后就能够像这样产生 Z 时间 2019-10-01T00:00:00Z 但几个小时后,它开始生成像这样的时区时间格式 2017-01-01T00:00:00+03:00

我还注意到,如果我重新启动服务器,它将不会有 Z 时间。我必须执行 Supervisorctl stop 和 start 然后它暂时似乎可以修复它。

这是我的主管重新启动的代码片段

/home/user/myapp/gunicorn_start.bash
/etc/supervisor/conf.d/myapp.conf
https://gist.github.com/axilaris/01525b78fcdc03071fcd34818820d7f1

这是我的服务器版本 Ubuntu 16.04.3 LTS

可能是什么问题以及如何修复它,以便始终产生 Zulu 时间。

最佳答案

我在这里注意到的第一件事是,您正在使用 serializers.DateTimeField--DRF doc用于年份表示的字段,其中年份始终是正整数 .

<小时/>

关于时区问题,Django使用TIME_ZONE settings在从数据库查询时。这是 postgress 中执行此操作时发生的最小 SQL 查询,

SELECT a,b,c,<b>DATE_TRUNC('year', "tracking_table"."created_at" AT TIME ZONE 'YOUR_TIME_ZONE_VALUE') AS "year"</b> FROM "tracking_table

但是,幸运的是,您可以在 tzinfo 的帮助下指定目标时区(在您的情况下为 UTC) TruncYear 中的 参数类。

示例

<b>import pytz</b>

Tracking.objects.annotate(year=<b>TruncYear('created_at', tzinfo=pytz.UTC)</b>)
<小时/>

要在 json 响应中显示年份,请将序列化器更改为,

class TimeseriesYearSerializer(serializers.ModelSerializer):
    venue = VenueTSSerializer(read_only=True)
    <b>year = serializers.IntegerField(read_only=True, source='year.year')</b>
    count = serializers.IntegerField(read_only=True)

    class Meta:
        model = Tracking
        fields = ['venue', 'year', 'count']
<小时/>

引用文献

  1. Postgress AT TIME ZONE
  2. Postgress date_trunc
  3. DRF Serializer source argument

关于python - Django 1.11 - 如何确保 TruncYear 生成 Zulu 时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58751806/

相关文章:

python - Matplotlib 在附加轴上的错误位置打勾

python - 根据运算结果对元组列表进行排序(除法)

sql - 缓慢同时写入 PostgreSQL 数据库中的同一个表

postgresql - 无法使用psql连接到dockerized postgres

python - 按用户定义的月份跨度对 pandas dataFrame 进行分组

python - Celery 工作人员之间共享 XMPP 连接

Python( Django ) pip 在 MacOS 中安装 psycopg2 错误

python - 'getattr() : attribute name must be string' error in admin panel for a model with an ImageField

postgresql - 低 Postgres 缓存命中率 - 数据大小或其他?

python - 如何在 django 中进行双重内连接?