Django Model IntegrityError: NOT NULL constraint failed: - python

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?

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.

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.

Related

Django restframework Error binding parameter

When trying to save the data in the DB I have this error:
sqlite3.InterfaceError: Error binding parameter 1 - probably unsupported type.
models.py
class Movie(Model):
title = CharField(max_length=255)
omdb = JSONField()
slug = SlugField(max_length=255, unique=True, allow_unicode=True)
views.py
omdb_data = get_movie(title) # returns response.json() from external API call
print(type(omdb_data['Title'])) # str
print(type(omdb_data)) # dict
movie = Movie(title=omdb_data['Title'],
omdb=omdb_data, slug=slugify(title))
movie.save() # crashing here
What could be wrong? I'm guess it's problem with title or omdb parameters (not sure if ID counts or not) but no idea whats wrong.
SQLite doesn't support all types data. It's in its name (Lite). You may try to convert to PostgreSQL or another complete database solution. Here is a tutorial for Django+Postgres but be careful, it's little bit outdated.

Odoo10 api constrains stuck

My constrains method not working for id_number. can't figure it out why.
from odoo import models, fields, api
from odoo.exceptions import ValidationError
class KindeGarden(models.Model):
_inherits = {'res.partner': 'partner_id'}
_name = 'kindergarten.model'
_description = 'Kindergarten'
age = fields.Integer(string="Amžius", required=False, default="1")
group = fields.Char(string="Grupė", compute="_compute_group", store=True)
height = fields.Float(string="Ūgis", required=False)
weight = fields.Float(string="Svoris", required=False)
id_number = fields.Integer(string="Registravimo Nr", required=True)
#api.constrains('id_number')
def _check_id_number_field(self):
for i in self:
if i.id_number < 10:
raise ValidationError("Number is to small")
and i'm also having this
WARNING -Kindegarden odoo.models.schema: Table 'kindergarten_model': unable to set a NOT NULL constraint on column 'id_number' !
If you want to have it, you should update the records and execute manually:
ALTER TABLE kindergarten_model ALTER COLUMN id_number SET NOT NULL
Like mentioned above, it looks like it is some data are null already before you set required parameter to true.
odoo has a shell you can use to access your DB if you are not familiar with SQL.
odoo-bin -d <database_name> shell
inside the shell, do as follow so you will see.
>> records = env['kindergarten.model'].search([('id_number','=',False)])
>> len(records)
if it returns a number aside from 0, it means that those are NULL value. so do like.
>> for record in records:
record.write({'id_number': 0.0})
>>env.cr.commit()
Then update your module again.
If this doesn't work you will need to do it manually with SQL.
Did you add constraint after few records were added ?
The error you got generally comes when postgres is unable to set "NOT NULL" to the column because it already has null values

Unknown IntegrityError in Django

I have this small project to create my bills through Django and Latex which worked flawlessly until today. Now when I try to add another costumer, Django throws
duplicate key value violates unique constraint "kunden_kundearbeitsamt_pkey"
DETAIL: Key (id)=(4) already exists.
These are the model definitions in question:
class Kunde(models.Model):
name = models.CharField('Name', max_length = 200)
vorname = models.CharField('Vorname', max_length = 200)
geburtsdatum = models.DateField('Geburtsdatum', max_length = 200)
untersuchungsdatum = models.DateField('Untersuchungsdatum', max_length = 200)
class Meta:
abstract = True
class KundeArbeitsamt(Kunde):
kundennummer = models.CharField('Kundennummer', max_length = 100)
bglnummer = models.CharField('BGL-Nummer', max_length = 100)
empfaenger = models.ForeignKey('rechnungen.NumberToEmpfaenger', blank = True, null = True)
class Meta:
verbose_name = "Proband Arbeitsamt"
verbose_name_plural = "Proband Arbeitsamt"
def __str__(self):
return '{}, {}'.format(self.name, self.vorname)
The admin part where the object is created (nothing special, I guess):
from django.contrib import admin
from .models import KundeArbeitsamt
class KundeArbeitsamtAdmin(admin.ModelAdmin):
ordering = ('name',)
admin.site.register(KundeArbeitsamt, KundeArbeitsamtAdmin)
I swear, I did not make any migrations or other changes to the database (Postgres) whatsoever. Django is handling the creation of the objects. What is causing this error and how to fix it?
This error is raised by your database, because django wants to add an new column with an ID (=4) already in use.
To investigate further you need to find the part of your app responsible for creating the IDs. Django usually delegates this task to your database. In case of postgres the datatype serial is used. Postgres uses so called sequences for this purpose and generates and executes the following SQL for you:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
I would now start with checking the database sanity like that:
-- views contents of the table
SELECT * FROM kunden_kundearbeitsamt;
-- check the sequence
select currval('kunden_kundearbeitsamt_id_seq');
If the first shows 4 records with IDs 1, 2, 3 and 4 and the sequence answers with 4 everything is alright. I would proceed with the django sources to figure out why they pass an ID on object creating without relying on the sequence. The django shell might be a good place to start with in that case.
Otherwise I would fix the sequence and ask myself how this happend as it is barely the case that postgres makes mistakes at this point.
SELECT setval('kunden_kundearbeitsamt_id_seq', (SELECT max(id) FROM kunden_kundearbeitsamt));

Django error with ForeignKey reference

I have a question about a ForeignKey reference problem with django.
This is a part of my code :
App ticketsTrader
class TicketsTrader(models.Model):
seller = models.ForeignKey(User, related_name='ticketsTrader_seller')
buyer = models.ForeignKey(User, related_name='ticketsTrader_buyer')
inscription = models.ForeignKey(Inscription)
transactionCode = models.CharField(max_length=30,blank=False,null=False)
...
App inscription
class Event(models.Model):
title = models.CharField(max_length=75)
description = models.TextField()
...
class Inscription(models.Model):
event = models.ForeignKey(Event)
packs = models.ManyToManyField(PackChoise)
user = models.ForeignKey(User)
...
def __unicode__(self):
return self.event.__unicode__() + u': ' + self.user.__unicode__()
def inscriptionKey(self):
return str(self.pk) + '_' + str(self.valkey)
But when I try to acces to the "Add Ticket Trader" interface in my Grapelli admin, I get an error message :
User matching query does not exist.
Python27\lib\site-packages\django\db\models\query.py in get, line 366
In template \grappelli\templates\admin\includes\fieldset.html, error
at line 19
What I want to get is : in the "inscription" column of my ticketTrader table get the value of the unique id (pk) of my "Inscription" table.
Or the value of the "inscriptionKey" but I don't think it's possible.
Django Version:1.4 / Python Version: 2.7.3 / South last version
Thanks for your help :)
I can only guess:
TicketsTrader has a foreign key to Inscription, which has a foreign key to User and uses that key in its __unicode__() method.
Now, I don't know Grapelli but the default admin app would render a dropdown for Inscription-s on the Add TicketsTrader page. If some of the Inscription-s pointed to non-existing User-s, then their __unicode__() method would fail with the error message you specified.
The question is how could some User-s be missing and Inscription-s pointing to them not. Well, if you use e.g. MySQL+MyISAM, foreign keys are not enforced there so all sorts of weird things can happen.
I think because you don't have any User... try create User before create Ticket Trader

ForeignKey model has no Manager (i.e., 'Foo' object has no attribute 'foo_set')

I have searched around for an answer to this but can't find one. When using a ForeignKey, I am consistently getting an error telling me that 'Foo object has no attribute 'foo_set'. I am a bit new to Django/Python, so I'm sure there is a simple answer here, but I haven't been able to find it so far. Here's some code (to store varied Boards for use in a game, each of which should have a number of Hexes associated with it):
Models:
class Boards(models.Model):
boardnum = models.IntegerField(unique=True)
boardsize = models.IntegerField(default=11)
hexside = models.IntegerField(default=25)
datecreated = models.DateTimeField(auto_now_add = True)
class Hexes(models.Model):
boardnum = models.ForeignKey(Boards, null = True)
col = models.IntegerField()
row = models.IntegerField()
cost = models.IntegerField(default=1)
Code (this works):
newboard, createb = Boards.objects.get_or_create(boardnum=boardn)
createb returns True.
Code (this immediately follows the above, and does not work):
try:
hx = newboard.boards_set.create(col=c, row=r)
except Exception, err:
print "error:", err
traceback.print_exc()
Both "err" and "traceback.print_exc()" give: AttributeError: 'Boards' object has no attribute 'boards_set'
I get the same error if I first create the Hexes record with a get_or_create and then try a newboard.boards_set.add() on it.
Any ideas? All suggestions appreciated.
The name that Django uses for a reverse foreign key manager is the name of the model that contains the foreign key, not the name of the model that the manager is on.
In your case, it will be:
newboard.hexes_set.create(col=c,row=r)
I find it useful to use the manage.py shell command to import your models and inspect them (with dir, etc) to check out all the available attributes.

Categories

Resources