Loaddata没有正确处理时间戳和时区

时间:2022-10-28 20:59:25

I'm using django 1.4.1 with mysql and timezones enabled. I did a dump data to yaml, modified some fields to create some test data, and am trying to load it back in. however, Django keeps complaining about naive datetimes even though a tz is specified

我正在使用启用了mysql和timezones的django 1.4.1。我向yaml做了一个转储数据,修改了一些字段以创建一些测试数据,并试图将其加载回来。但是,即使指定了tz,Django也会抱怨天真的日期时间

specifically, my loaddata has:

具体来说,我的loaddata有:

fields: {created_date: !!timestamp '2012-09-15 22:17:44+00:00', ...

but loaddata gives the error:

但loaddata给出错误:

RuntimeWarning: DateTimeField received a naive datetime (2012-09-15 22:17:44) while time zone support is active.

This doesn't make much sense to me, seeing as its:

这对我来说没有多大意义,因为它看起来像:

  1. a UTC timestamp
  2. UTC时间戳

  3. the same exact format Django exported using dumpdata
  4. Django使用dumpdata导出的格式相同

is there some way i can tell django this is a UTC date?

有什么方法可以告诉django这是一个UTC日期吗?

3 个解决方案

#1


9  

From the docs...

来自文档......

When serializing an aware datetime, the UTC offset is included, like this:

序列化感知日期时间时,包括UTC偏移量,如下所示:

"2011-09-01T13:20:30+03:00"

For a naive datetime, it obviously isn't:

对于一个天真的日期时间,它显然不是:

"2011-09-01T13:20:30"

...so instead of...

......所以不是......

created_date: !!timestamp '2012-09-15 22:17:44+00:00'

...either of...

created_date: '2012-09-15T22:17:44+00:00'

...or...

created_date: '2012-09-15T22:17:44Z'

...will work.

#2


19  

The problem stems from PyYAML. When loaddata hands off the datetime to PyYAML, it takes the aware datetime, adjusts the time to UTC, and then returns a naive datetime, which generates the warning.

问题源于PyYAML。当loaddata将日期时间移交给PyYAML时,它需要知道日期时间,将时间调整为UTC,然后返回一个天真的日期时间,从而生成警告。

There is a Django ticket, as well as a PyYAML ticket concerning the issue. Both go into far greater detail concerning the unexpected behavior above. Judging by the comments in the tickets, this issue seems unlikely to be resolved anytime soon.

有一个Django票,以及有关该问题的PyYAML票。两者都涉及上述意外行为的更多细节。从票证中的评论来看,这个问题似乎不太可能很快得到解决。

Is you set TIME_ZONE = 'UTC' in settings.py of your project, you will load in the correct time, but you will still get warnings. Should your timezone be set to anything else, Django will treat the datetime as local, and adjust it to UTC, which is probably undesired.

您是否在项目的settings.py中设置了TIME_ZONE ='UTC',您将在正确的时间加载,但仍会收到警告。如果你的时区被设置为其他任何东西,Django会将日期时间视为本地时间,并将其调整为UTC,这可能是不受欢迎的。

The best way to avoid this is to use JSON as a serialization format.

避免这种情况的最佳方法是使用JSON作为序列化格式。

Hope that helps.

希望有所帮助。

#3


1  

You can copy django/core/serializers/pyyaml.py to your project dir, and replace following code (maybe 78-79 lines in the case of ver.1.9.9)

你可以将django / core / serializers / pyyaml.py复制到你的项目目录,并替换下面的代码(在ver.1.9.9的情况下可能是78-79行)

for obj in PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options):
    yield obj

to

output = yaml.load(stream, Loader=SafeLoader)
for a_model in output:
    for key, value in a_model.items():
        if key == 'fields':
            for vkey, vvalue in value.items():
                if isinstance(vvalue, datetime.datetime):
                    value[vkey] = vvalue.replace(tzinfo=pytz.utc)
for obj in PythonDeserializer(output, **options):
    yield obj

of course pytz already installed and

当然pytz已经安装和

import pytz

is needed.

This code will convert all naive datetime values to UTC aware.

此代码将所有天真的日期时间值转换为UTC识别。

To override default serializer, add SERIALIZATION_MODULES in settings.py:

要覆盖默认序列化程序,请在settings.py中添加SERIALIZATION_MODULES:

SERIALIZATION_MODULES = {'yaml': 'yourproj.pyyaml'}

I hope this monkey patch works fine.

我希望这个猴子补丁工作正常。

#1


9  

From the docs...

来自文档......

When serializing an aware datetime, the UTC offset is included, like this:

序列化感知日期时间时,包括UTC偏移量,如下所示:

"2011-09-01T13:20:30+03:00"

For a naive datetime, it obviously isn't:

对于一个天真的日期时间,它显然不是:

"2011-09-01T13:20:30"

...so instead of...

......所以不是......

created_date: !!timestamp '2012-09-15 22:17:44+00:00'

...either of...

created_date: '2012-09-15T22:17:44+00:00'

...or...

created_date: '2012-09-15T22:17:44Z'

...will work.

#2


19  

The problem stems from PyYAML. When loaddata hands off the datetime to PyYAML, it takes the aware datetime, adjusts the time to UTC, and then returns a naive datetime, which generates the warning.

问题源于PyYAML。当loaddata将日期时间移交给PyYAML时,它需要知道日期时间,将时间调整为UTC,然后返回一个天真的日期时间,从而生成警告。

There is a Django ticket, as well as a PyYAML ticket concerning the issue. Both go into far greater detail concerning the unexpected behavior above. Judging by the comments in the tickets, this issue seems unlikely to be resolved anytime soon.

有一个Django票,以及有关该问题的PyYAML票。两者都涉及上述意外行为的更多细节。从票证中的评论来看,这个问题似乎不太可能很快得到解决。

Is you set TIME_ZONE = 'UTC' in settings.py of your project, you will load in the correct time, but you will still get warnings. Should your timezone be set to anything else, Django will treat the datetime as local, and adjust it to UTC, which is probably undesired.

您是否在项目的settings.py中设置了TIME_ZONE ='UTC',您将在正确的时间加载,但仍会收到警告。如果你的时区被设置为其他任何东西,Django会将日期时间视为本地时间,并将其调整为UTC,这可能是不受欢迎的。

The best way to avoid this is to use JSON as a serialization format.

避免这种情况的最佳方法是使用JSON作为序列化格式。

Hope that helps.

希望有所帮助。

#3


1  

You can copy django/core/serializers/pyyaml.py to your project dir, and replace following code (maybe 78-79 lines in the case of ver.1.9.9)

你可以将django / core / serializers / pyyaml.py复制到你的项目目录,并替换下面的代码(在ver.1.9.9的情况下可能是78-79行)

for obj in PythonDeserializer(yaml.load(stream, Loader=SafeLoader), **options):
    yield obj

to

output = yaml.load(stream, Loader=SafeLoader)
for a_model in output:
    for key, value in a_model.items():
        if key == 'fields':
            for vkey, vvalue in value.items():
                if isinstance(vvalue, datetime.datetime):
                    value[vkey] = vvalue.replace(tzinfo=pytz.utc)
for obj in PythonDeserializer(output, **options):
    yield obj

of course pytz already installed and

当然pytz已经安装和

import pytz

is needed.

This code will convert all naive datetime values to UTC aware.

此代码将所有天真的日期时间值转换为UTC识别。

To override default serializer, add SERIALIZATION_MODULES in settings.py:

要覆盖默认序列化程序,请在settings.py中添加SERIALIZATION_MODULES:

SERIALIZATION_MODULES = {'yaml': 'yourproj.pyyaml'}

I hope this monkey patch works fine.

我希望这个猴子补丁工作正常。