Q-bart
Q-bart

Reputation: 1591

Django Model IntegrityError: NOT NULL constraint failed:

I am building a service that makes short URLs. I have the models:

from django.db import models

class ShortURL(models.Model):
    url = models.CharField(max_length = 50)

class LongURL(models.Model):
    name = models.CharField(max_length = 100, null=True)
    url_to_short = models.ForeignKey(ShortURL)

I have already run the command: python manage.py migrate If I open the interpreter, using python manage.py shell and run this code:

>>> from appshort.models import LongURL
>>> a = LongURL(name = 'hello_long_link')
>>> a.save()

then I get the error:

django.db.utils.IntegrityError: NOT NULL constraint failed: appshort_longurl.url_to_short_id

What did I do wrong?

Upvotes: 4

Views: 20792

Answers (2)

Amiay Narayan
Amiay Narayan

Reputation: 529

While creating an entry for LongURL you must create an object of ShortURL or filter out already existing (because ForeignKey field cannot be left blank). Additionally, you say that sometimes you have been able to achieve the desired behaviour. This can be so because at those places you would have got an object of ShortURL which is not null. However, the error in the discussion arises, when you try to send a null object during the creation of LongURL. For example:

...
short_url_obj = ShortURL.objects.filter(...).first()
# you have to ensure that this above query is not null
try: 
    new_long_url = LongURL(url_to_short=short_url_obj, name="some_name")
    new_long_url.save()

except:
    # if the short_url_obj is null
    print("The short_url_obj was null, cannot save to database")

...

One can also use if-else block instead, but I would not advice that.

Upvotes: 0

wim
wim

Reputation: 362707

class LongURL(models.Model):
    name = models.CharField(max_length = 100, null=True)
    url_to_short = models.ForeignKey(ShortURL)

The way you have set it up, the url_to_short foreign key is not optional. So when you try to save:

>>> a = LongURL(name = 'hello_long_link')
>>> a.save()

Django is trying to tell you that you didn't provide the url_to_short relation on your a model instance.

You'll need to either

  • Provide the ShortURL relation when you create the LongURL instance
  • Make the url_to_short relation optional with null=True, blank=True.

Upvotes: 6

Related Questions