Django: null value in column "created_at" violates not-null constraint - django

I'm trying to add records via the code below:
Post.objects.update_or_create(
user=user,
defaults={
"title": external_post.get('title'),
"body": external_post.get('body'),
"seo": external_post.get('seo')
}
)
I've successfully migrated the model but I'm getting the error " null value in column "created_at" violates not-null constraint".
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

I faced this same problem when I was using the #transaction atomic decorator in Django. Basically the reason why I faced the same error was that I was not using the default auto-increment ID in one of my models but rather I had specified a particular field as the primary key using primary_key=True
As a result my data contained two primary keys that were the same. This resulted in an 'update' operation rather than a 'create' operation in the database.
So, Django was trying to update an entry but the created_at field was missing hence the error.
I would suggest you do this instead:
post,created = Post.objects.update_or_create(
user=user,
defaults={
"title": external_post.get('title'),
"body": external_post.get('body'),
"seo": external_post.get('seo')
})
if created:
# your code goes here
#(this ensures that the code is executed only if an entry is getting created in the database)
You can read this for a better explaination: https://code.djangoproject.com/ticket/17654

Related

Getting Integrity & NotNull errors for null value in DateField column when null and blank attributes have been set to True

I'm currently using a Django backend, with a React/Redux frontend. When I try to add a new "Day" to my database, I get:
psycopg2.errors.NotNullViolation: null value in column "day_date" ... violates not-null constraint
DETAIL: Failing row contains (2, null, Tu).
django.db.utils.IntegrityError: null value in column "day_date" ... violates not-null constraint
DETAIL: Failing row contains (2, null, Tu).
This shouldn't be an issue because in my model, day_date is a DateField:
class Day(models.Model):
day_id = models.AutoField(primary_key=True)
day_date = models.DateField(blank=True, null=True)
day_str = models.CharField(max_length=30, blank=True)
class Meta:
db_constraints = {
'CHK_DayNotNull': 'CHECK (day_date IS NOT NULL OR day_str <> "")'
}
I thought maybe it was an error with my constraint, but when I deleted the constraint I get the same error. I tried playing with the inputs of the day_date field in the model; I tried all the combinations and get the same error which makes me think something is wrong with how my database is being updated. I'm using PostgreSQL for my database.
I tried clearing cache. deleting all my migrations, and then running,
python3 manage.py flush
python3 manage.py makemigrations
python3 manage.py migrate
but I'm still getting the exact same error.

Django fixtures and auto_now_add date time field

Trying to create a fixture for a model with an auto_now_add date time field
created_at = models.DateTimeField(auto_now_add=True)
When the fixtures is loaded there is an error thrown IntegrityError: Problem installing fixture, null value in column "created_at" violates not-null constraint
Is there a way to have Django determine the date rather than manually entering a date?
[
{
"model": "customer.type",
"pk": 1,
"fields": {
"name": "type",
"created_by": 1
}
}
]
One of the easy workaround will be using the default--[DjangoDoc] and editable--[DjangoDoc] arguments together,
from django.utils import timezone
class Foo(models.Model):
...
created_at = models.DateTimeField(default=timezone.now, editable=False)
The above solution tested and verified under Django 2.1 and Python 3.6 environment.
Drawback of this method
From the Django-Doc of DateField.auto_now_add
Automatically set the field to now when the object is first created. Useful for creation of timestamps. Note that the current date is always used; it’s not just a default value that you can override. So even if you set a value for this field when creating the object, it will be ignored. If you want to be able to modify this field, set the following instead of auto_now_add=True
Which means, this setting will override the timezone.now() value if you manually provide any valid datetime.

how to update unique field for multiple entries in django

I have a simple Django model similar to this:
class TestModel(models.Model):
test_field = LowerCaseCharField(max_length=20, null=False,
verbose_name='Test Field')
other_test_field = LowerCaseCharField(max_length=20, null=False, unique=True,
verbose_name='Other Test Field')
Notice that other_test_field is a unique field. Now I also have some data stored that looks like this:
[
{
test_field: "object1",
other_test_field: "test1"
},
{
test_field: "object2",
other_test_field: "test2"
}
]
All I'm trying to do now is switch the other_test_field fields in these two objects, so that the first object has "test2" and the second object has "test1" for other_test_field. How do I accomplish that while preserving the uniqueness? Ultimately I'm trying to update data in bulk, not just swapping two fields.
Anything that updates data in serial is going to hit an IntegrityError due to unique constraint violation, and I don't know a good way to remove the unique constraint temporarily, for this one operation, before adding it back. Any suggestions?

Django Many to Many migration can't insert null into id

I'm trying to migrate a column from a Char field to a Many-to-Many field running Django 1.8.2. I'm doing a custom Data Migration, to move the data properly. When I try to migrate, I get a database error, can't insert null into the many to many table id column.
My models, simplified:
class LicenseArea(models.Model):
#appraisal_account = models.CharField(max_length=17, null=True, db_index=True)
appraisal_account = models.ManyToManyField(TaxAccount, db_table='LicAreaTaxAccount', related_name='accounts_for_license_area', related_query_name='license_area_for_account', null=True)
class TaxAccount(models.Model):
account = models.CharField(max_length=17, db_index=True)
So I first create TaxAccount objects in a RunPython block, then remove the old field and add the new one, like so:
migrations.RunPython(create_tax_account_objects),
migrations.RemoveField(
model_name='licensearea',
name='appraisal_account',
),
migrations.AddField(
model_name='licensearea',
name='appraisal_account',
field=models.ManyToManyField(related_query_name='license_area_for_account', related_name='accounts_for_license_area', db_table='licenses_LicAreaTaxAccount', to='licenses.TaxAccount'),
),
All that works. My issue comes when I try to migrate the data, relating the LicenseArea object with its corresponding TaxAccount object. In another RunPython block, I try the code shown below (I've tried in both directions; acct.licensearea_set.add indicates that the TaxAccount model has no licensearea_set attribute, while the second option shown below gives me the IntegrityError (ORA-01400) that I can't insert null into the ID column :
for la in LicenseArea.objects.all():
acct = TaxAccount.objects.get(account=la.appraisal_account_temp)
#acct.licensearea_set.add(la)
#la.appraisal_account.add(acct)
How do I solve this? Thanks in advance.

get_or_create failure with Django and Postgres (duplicate key value violates unique constraint)

Thanks for taking time to read my question.
I have a django app with the following model:
class UserProfile(models.Model):
user = models.OneToOneField(User)
...
class Visit(models.Model):
profile = models.ForeignKey(UserProfile)
date = models.DateField(auto_now_add=True, db_index=True)
ip = models.IPAddressField()
class Meta:
unique_together = ('profile', 'date', 'ip')
In a view:
profile = get_object_or_404(Profile, pk = ...)
get, create = Visit.objects.get_or_create(profile=profile, date=now.date(), ip=request.META['REMOTE_ADDR'])
if create: DO SOMETHING
Everything works fine, except that the Postgres Logs are full with duplicate key errors:
2012-02-15 14:13:44 CET ERROR: duplicate key value violates unique constraint "table_visit_profile_id_key"
2012-02-15 14:13:44 CET STATEMENT: INSERT INTO "table_visit" ("profile_id", "date", "ip") VALUES (1111, E'2012-02-15', E'xx.xx.xxx.xxx') RETURNING "table_visit"."id"
Tried different solution e.g.
from django.db import transaction
from django.db import IntegrityError
#transaction.commit_on_success
def my_get_or_create(prof, ip):
try:
object = Visit.objects.create(profile=prof, date=datetime.now().date(), ip=ip)
except IntegrityError:
transaction.commit()
object = Visit.objects.get(profile=prof, date=datetime.now().date(), ip=ip)
return object
....
created = my_get_or_create(prof, request.META['REMOTE_ADDR'])
if created: DO SOMETHING
This only helps for MySQL? Does anyone know how to avaid the duplicate key value errors for postgres?
Another possible reason for these errors in get_or_create() is data type mismatch in one of the search fields - for example passing False instead of None into a nullable field. The .get() inside .get_or_create() will not find it and Django will continue with new row creation - which will fail due to PostgreSQL constraints.
I had issues with get_or_create when using postgres. In the end I abandoned the boilerplate code for traditional:
try:
jobInvite = Invite.objects.get(sender=employer.user, job=job)
except Invite.DoesNotExist:
jobInvite = Invite(sender=employer.user, job=job)
jobInvite.save()
# end try
Have you at some point had unique=True set on Visit's profile field?
It looks like there's been a unique constraint generated for postgres that's still in effect. "table_visit_profile_id_key" is what it's auto generated name would be, and naturally it would cause those errors if you're recording multiple visits for a user.
If this is the case, are you using South to manage your database changes? If you aren't, grab it!
PostgreSQL behaves somewhat differently in some subtle queries, which results in IntegrityError errors, especially after you switch to Django 1.6. Here's the solution - you need to add select_on_save option to each failing model:
class MyModel(models.Model):
...
class Meta:
select_on_save = True
It's documented here: Options.select_on_save