0

I have implemented some models and migrations into my postgreSQL9.4 database works. I have some models. For an example the SkillLevelRuleModel:

class SkillLevelRule(models.Model):
skillLevelRuleID = models.AutoField(primary_key=True)
skillCategoryID = models.ForeignKey(SkillCategory, default=1)
skillLevelID = models.ForeignKey(SkillLevel, default=1)
threshold = models.IntegerField()
validFrom = models.DateTimeField(default=datetime.now)
validTo = models.DateTimeField(auto_now_add=False, auto_now=True)

Now I have a problem with the following field:

validTo = models.DateTimeField(auto_now_add=False, auto_now=True)

So it should have no value in the beginning when the model is created, but as soon as an entry in the model is updated, validTO should be updated.

As soon as I have created the model (makemigrations, migrate) I want to load an initial_data.json to load initial data.

Sadly I get the following error:

Could not load rewardsystem.SkillLevelRule(pk=6): null value in column "validTo" violates not-null constraint
DETAIL:  Failing row contains (6, 2, 2016-02-11 08:46:29.267201+00, null, 1, 1).

My .json file and the respective entry for this models looks like the following:

{
    "model": "rewardsystem.SkillLevelRule",
    "pk": 6,
    "fields":{
        "skillCategoryID" : "1",
        "skillLevelID" : "1",
        "threshold" : "2"
    }
},

I do not understand why this happens and how I should prevent it. I do not want that the validTo field is set in the beginning. Why? This model saves rules or let's say thresholds. They are valid from the beginning, when the model is instantiated. Maybe at some point when the system is running, an administrator likes to change some rules. Therefore he should be able to specify until when a certain rule WAS VALID (validTO).

Moe Far
  • 2,742
  • 2
  • 23
  • 41
Dante
  • 45
  • 1
  • 6

1 Answers1

0
validTo = models.DateTimeField(auto_now=True,blank=True,null=True)

auto_now_add is similar to auto_now, but it adds "now" only once when the record is created. If you use auto_now, it will save for the initial add, just like the auto_now_add functionality, then continue to update to "now" on each record update.

It seems there is a null in this field, which should not be null, maybe because of this wrong definition.

  1. Fix the field.
  2. Load the data
  3. Loop through all the objects, and save(). This will add the now datetime to missing rows.
  4. Now you can remove the blank=True, null=True, makemigrations, and migrate.

To loop and save (step 3) create the following python script and run it from shell:

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings") #copy from manage.py
os.environ["DJANGO_SETTINGS_MODULE"] = "mysite.settings"
import django
django.setup()
from mysite.myapp.models import SkillLevelRule
q = SkillLevelRule.objects.all()
for s in q:
   q.save()
Aviah Laor
  • 3,620
  • 2
  • 22
  • 27
  • This does not solve my problem. Even if I have the field (auto_now=True) the integrity error still pops up...Maybe something wrong with my fixture? I mean I create the model and then I want to load it with initial data. But in this initial_data the 'validTo' date should not be required. How should I do this? – Dante Feb 11 '16 at 10:37
  • There is a record without a validTo field, which should not been null, but it is. Maybe the wrong definition caused it. – Aviah Laor Feb 11 '16 at 11:17
  • I am sorry, but the solution you provided seemed like overkill to me. So I tried something different which worked for me in the end. I just defined the DateTimeField like the following: `validTo = models.DateTimeField(blank=True, null = True)` Like this I can manually set the validTo field whenever I want. – Dante Feb 15 '16 at 16:54
  • No problem, I tried to answer with the auto_now, which was the reason for the question in the first place. Of course that with null and blank there is no issue. – Aviah Laor Feb 15 '16 at 17:00
  • Yep. Sorry for the inconvenience. Don't want to be rude, but my Django knowledge is not that advanced so I do not understand your solution fully so I was not able to try this out.... – Dante Feb 15 '16 at 17:02