Loaddata not dealing with timestamps and timezones properly

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.

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.

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.

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

Hope that helps.


From the docs...

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

"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.


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)

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

import pytz

is needed.

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

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

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

I hope this monkey patch works fine.