So I am trying to add a point field to a model in django which looks like this:
class Location(models.Model):
lat = models.FloatField(blank=True, null=True)
lng = models.FloatField(blank=True,null=True)
geometry = models.PointField(srid=4326,default='POINT(0.0,0.0)')
objects = models.GeoManager()
I already have database with lots of locations with the lat lng coordinates but they don't need a point field. I am getting this error django.db.utils.IntegrityError: column "geometry" contains null values
I set the default but it still gives me that error when I run 'python manage.py migrate' How can I fix this?
The default does not change old rows in the database (that existed before the migration). You should set the the geometry field to be nullable and then migrate. Once migrated you can either fill in the null values with the default and remove null=True or leave as is
UPDATE
Based on this post it seems very possible that PointField cannot be null (even if it's specified to be which really grinds my gears...). GIVEN that your model does not need to change but it doesn't look like django can handle this super well for you.
I see two options (better ones might exist)
Do the data migration on the actual table yourself (I THINK with most databases when you add in a new column you can set a default there and it will populate that for you)
Create a new model which is essentially the same with the new columns, copy the data over, delete the old model and columns.
Neither of these seem ideal but the googles have not yet shown me a better way
Related
In one of my tables I have a field game_fen_when_leave = models.TextField(). But it gives me an error "You are trying to add a non-nullable field 'game_fen_when_leave' to game without a default; we can't do that (the database needs something to populate existing rows)". Is it necessary for this field to have a default value? I saw an example without having a default.
Short answer
When creating a new model: No it is not
When adding it to an existing model: Yes it is
A bit more on the topic:
With the information given I guess your are about to add this new field to an existing table.
When adding a new non-nullable fields to an existing model you will need to provide a default value. This is because there might already be rows in that particular table and those would need a default value to populate this new field with. (I'm actually just repeating the error message here.)
In the example that you are referring:
The model is new and there cannot be existing rows that would need to be populated with default values. Therefore default value for the TextField is not needed.
Couple of possibilities
Remove and create the model from scratch: If you remove the table by migrations and create it again as a completely new table. You don't have to provide a default value as there cannot be existing rows.
Add a default value: Default value could simply be an empty string and that probably is the way to go.
By default Django TextField is a non-nullable yes. You have the power to change that, but it is not advised to do so:
https://docs.djangoproject.com/en/3.0/ref/models/fields/#null
If a string-based field has null=True, that means it has two possible
values for “no data”: NULL, and the empty string.
I have two models, foo and bar. They already exists in my database with many instances each. Now, I realized that there is a relation that should be added. Therefor, I wish to add a ForeignKey betweenfoo and bar.
class foo():
# lots of stuff
bar = models.ForeignKey(bar, related_name='foo', null=True)
I actually don't want the key to be nullable, but since they already exists, I need to add it because the existing rows need to be populated.
Can I later remove the null=True parameter once all instances have the foreignKey field are populated?
Yes you can, basically to reach this you need to do three steps
Create a first migration, where you create your field as nullable
Create a second migration to populate already existing fields
Create a third migration where you set the field as not nullable
A very good step by step is explained here
I am new to Django.
I was trying to design a model in django. First I did with adding some fields, then I migrated the code. Later I found that I should have some other fields. I added some new fields, let say a CharField. Then while I was doing the migration, its showing error like you are trying to add a non-nullable field without a default. Can anybody tell should I add every time a default value to a new field OR Is there any other way to handle this?
You would need to add null=True to the field parameter that gives you this error in your model to allow for null values or give it a default value default=<value> and then re-run your migration
I am using solr search in django. When I am rebuilding the index with Solr, I get the following error:
model 'X' has an empty model_attr 'company' and doesn't allow a default or null value.
Does anyone know mistake I made, and how can I solve this issues.
It seems that you have some entries in your database where a mandatory field is left empty. This can be caused by adding a new mandatory field to an existing model so that existing instances of the model are invalidated due to the empty field.
If you want to enforce the field to have a value, you need to give the existing instances a value for the field. If you use the migration tool south it will give you an interactive prompt to fix the problem. Check out the "Data Migration" section of the south documentation.
If it is okay for you to leave the field optional, set blank=True (allows leaving the field blank) and null=True (sets NULL for empty field).
You need to add it as
indexes.CharField(model_attr='company', null=True)
and if you want to allow the blank then
add blank=True
indexes.CharField(model_attr='company', blank=True, null=True)
I'm using South with a Postgresql DB for a Django project.
There is a model field that I'd like to change the default value for going forward. I dont need previous records effected. Just new records.
Do I need to do a migration for this, or just change the model?
OLD FIELD DETAIL:
background_style = models.CharField(max_length=1, choices=BACKGROUND_STYLE, default=BackgroundStyleCode.CENTERED)
NEW FIELD DETAIL:
background_style = models.CharField(max_length=1, choices=BACKGROUND_STYLE, default=BackgroundStyleCode.STRETCHED)
(model name is "Page")
You should run a migration. Any time you make a change to a model, no matter how insignificant, you should create a schema migration so that you can move backwards and forwards to any point in time without any "magic" edits.