djangonauts / django-hstore

PostgreSQL HStore support for Django.
http://django-hstore.readthedocs.io/
Other
517 stars 142 forks source link

Why forcing DatetimeField to utcnow() ? #82

Closed oleiade closed 9 years ago

oleiade commented 9 years ago

Hi!

We've started using your library @komoot and we've rapidly hit the problem that it is impossible to give a None value to a DateTimeField in schema mode.

This part of the code: https://github.com/djangonauts/django-hstore/blob/c5d9b46fa6a678e864c32ed29ee63e37f26df3ca/django_hstore/virtual.py#L102

Seems to indicate that any default value set to None will be converted to datetime.utcnow(). Is there a reason for this specific behavior? If I'm not mistaken django ORM authorizes None values for DateTimeField if null=True.

Our workaround for now is to set 'kwargs': {'default': ''}, however it forces our schema to be in a quiet inconsistent state...

Thanks for your explanation :-)

nemesifier commented 9 years ago

Hi @oleiade,

this is a bug.

You can either send a failing test case and a fix or wait for me or someone else to fix it in the following weeks.

Thank for reporting it.

Federico

oleiade commented 9 years ago

Will give it a shot then :-)

daaray commented 9 years ago

Setting it to datetime.utcnow() by default also causes issues with migrations (1.7 specifically in our case). The default should be a callable, rather than the evaluation of the callable, if that makes sense. An older but still relevant walkthrough of the issue.

The current implementation forces a new migration if one has not set a default value for the DateTimeFied virtual field:

        migrations.AddField(
            model_name='answer',
            name='datetime',
            field=django_hstore.virtual.VirtualField(default=datetime.datetime(2014, 12, 12, 14, 45, 40, 836174)),
            preserve_default=True,
        ),

We bypass this, at present, by explicitly setting the default in the schema definition as follows:

from django.utils.timezone import now

class Answer(models.Model):
    """
    The recorded answer for a Question
    """
    question = models.ForeignKey(Question)
    answer = hstore.DictionaryField(
        null=True, blank=True,
        schema=[
...
            {
                'name': 'datetime',
                'class': 'DateTimeField',
                'kwargs': {
                    'default': now
                }
            },
...
nemesifier commented 9 years ago

how can we produce a failing test case for this?

nemesifier commented 9 years ago

@oleiade @daaray check out the latest changes on master (1.3.6 alpha), it would be very helpful if you could test them on your environment and provide feedback.

nemesifier commented 9 years ago

Will close this in 1 week if no feedback.