null value in column after migration on different git branch - django

My model:
class Item(models.Model):
name = models.CharField(...)
description = models.CharField(...)
I run manage.py makemigrations and manage.py migrate
Then I switched to another git branch where description field doesn't exist yet but when I try to create new Item object I see:
null value in column "description" violates not-null constrain
What is the best way to fix that?

Your database has a column which is not in your new branch.
So, either drop that column from your database, or create a new DB.
One more option is to go back to the previous branch, make the description nullable by updating its definition to:
description = models.CharField(null=True...)
and then run the makemigrations and migrate commands.

Related

How to add in Django a non-nullable ForeignKey to an existing table?

I have the following models:
class Parent(models.Model):
name = CharField(max_length=80, ...)
class Child(models.Model):
name = CharField(max_length=80, ....)
And I want to add a non-nullable foreign key as shown here:
class Child(models.Model):
name = CharField(max_length=80, ....)
parent = ForeignKey(parent)
Both tables already exists in the database but have no data.
When running makemigrations Django asks for a default value. If I don't want to provide a default value, is it better to perform 2 migrations, the first one with null=True and then run a second one with null=False, before ingesting data in the DDBB?
Thank you for your advice.
Running two migrations would not solve anything. While running second migration you would get again warning that you have to provide a default value.
What is your intention with the existing Child instances? How do you plan to fill the parent column?
If there is no data in both the tables then it does not matter what you select to provide one-off default value just set it to 1 (in case of foreign key it works as ID, but as there is no data it does not matter).
If there is data in those tables then you have to do a 2 step migration first with null=True, then migrate data in migration script and then set it to null=False.

Is there any way to alter add table column in django?

Table name is TestTable. How can I add a new column to the table which is hold in markAtrr variable?
Means how can I perform this query in django?
ALTER TABLE table_name
ADD column_name column_definition;
def createTest(request):
markAttr=request.POST.get('Attr')
obj=TestTable()
I feel you need to read the documentation harder, or work through the tutorials again.
A django Model subclass describes a database table. After you have created it for the first time you run the management commands
./manage.py makemigrations
and if there are no errors to fix,
./manage.py migrate
this latter creates a new table for your app in the database, connected to your model definition.
If you want to add a column to that model (or delete a column, or change the attributes of a column) you editing the model definition to add a field (column definition) and then again makemigrations and upon success, migrate. Your forms, views etc. can then be modified to use the column/field which migration has added or altered.

Revert migration on deleted not null field

I've got a model with a non-null field which I deleted:
class Spam(models.Model):
slug = models.SlugField(allow_unicode=True) # deleted
After I made the migrations and applied them, I wanted to revert them.
But obviously, this results in
django.db.utils.IntegrityError: NOT NULL constraint failed: eggs_spam.slug
How can I revert the migration?
There is an easier way:
Find migration where you have initially add slug field
Add default value to slug field
Unapply last migration
Remove default value from initial slug field migration
That's tricky. The only solution I can think of is the following:
1: First, create a migration that allows the slug field to be nullable
2: Then, create another migration that will populate the field for every row
3: Lastly, create a migration that makes the field non-nullable.
Hope it helps

Can't migrate Django models with foreign key constraints

I have a model with a foreign key field. I want to remove the foreign key reference. However, migration fails because of the following error:
Cannot delete or update a parent row: a foreign key constraint fails
I understand what is going on, but I don't know how to resolve this properly with Django. Right now (since I'm at the beginning of my project), I go into the MySQL database manually and delete the tables and re-migrate as if it was the first migration.
Is there a way, using Django, to get around this foreign key constraint issue?
I'm using Django 1.7
Database backend is MySQL
EDIT - Models Before/After migrations
Before:
class Skills(models.Model):
# fields here...
class Project(models.Model):
skills = models.ForeignKey(Skills, verbose_name = "Required Skills", blank = True, null = True)
After:
class Skill(models.Model):
# fields here...
class Project(models.Model):
skills = models.ForeignKey(Skill, verbose_name = "Required Skills", blank = True, null = True)
I'm pretty sure all I've done is removed the "Plural" from the Skill model. The the makemigrations command works fine, but the migrate command fails with the above noted error.
EDIT 2
Hit the same error:
Cannot drop column 'skills_id': needed in a foreign key constraint 'projects_project_skills_id_4cc7e00883ac4de2_fk_projects_skill_id'
This time I dropped the field skill from model Project
A little hack I used:
Add a migration operations that first alters the field to say IntegerField before other operations i.e
operations = [
migrations.AlterField(
model_name='projects_project',
name='skills',
field=models.IntegerField(default=0)
),
..... other migration entries now after this.
]
This is my SOLUTION (do this manually first)
ALTER TABLE forms_formentry DROP FOREIGN KEY
forms_formentry_form_id_d0f23912_fk_forms_form_page_ptr_id
This is the ERROR
django.db.utils.OperationalError: (1833, "Cannot change column 'page_ptr_id': used in a foreign key constraint 'forms_formentry_form_id_d0f23912_fk_forms_form_page_ptr_id' of table 'dbname.forms_formentry'")

Django South - Create Not Null ForeignKey

I have a Model
class Mystery(models.Model):
first = models.CharField(max_length=256)
second = models.CharField(max_length=256)
third = models.CharField(max_length=256)
player = models.ForeignKey(Player)
I added the player ForeignKey but when I try to migrate it using South it seems that I can't create this whith a null=False. I have this message :
The field 'Mystery.player' does not have a default specified, yet is
NOT NULL. Since you are adding this field, you MUST specify a default
value to use for existing rows. Would you like to:
1. Quit now, and add a default to the field in models.py
2. Specify a one-off value to use for existing columns now
I use this command :
manage.py schemamigration myapp --auto
Thanks a lot !
This is best accomplished in 3 migrations.
Step 1. Create the new model and allow player to be null: player = models.ForeignKey(Player, null=True)
Step 2. Run ./manage.py schemamigration <app> --auto
Step 3. Run ./manage.py datamigration <app> set_default_players
Step 4. Update forwards and backwards in <app>/migrations/<number>_set_default_players.py to use whatever logic you like for setting the default player. Ensure that every Mystery object has a value for player.
Step 5. Update the Mystery model so that player has null=False.
Step 6. Run ./manage.py schemamigration <app> --auto
Step 7. Run ./manage.py migrate <app>
Another option is to create a data migration before adding the ForeignKey, in which you create a new Player instance with a specific id. Be sure that that id does not exist previously in your database.
1.Create the data migration file
$ ./manage.py datamigration myapp add_player
Created 00XX_add_player.py
2.Edit the forwards and backwards methods of the file:
def forwards(self, orm):
orm['myapp.Player'].objects.create(name=u'Very misterious player', id=34)
def backwards(self, orm):
# Haven't tested this one yet
orm['myapp.Player'].objects.filter(id=34).delete()
3.Add the ForeignKey to your Mistery class and migrate the schema again. It will ask for the default value to your data migration id, in this example, 34.
$ ./manage.py schemamigration --auto myapp
? The field 'Mistery.player' does not have a default specified, yet is NOT NULL.
? Since you are adding this field, you MUST specify a default
? value to use for existing rows. Would you like to:
? 1. Quit now, and add a default to the field in models.py
? 2. Specify a one-off value to use for existing columns now
? Please select a choice: 2
? Please enter Python code for your one-off default value.
? The datetime module is available, so you can do e.g. datetime.date.today()
>>> 34
+ Added field player on myapp.Mistery
Created 0010_auto__add_field_mistery_player.py. You can now apply this migration with: ./manage.py migrate myapp
4.Finally run the migrate command and it will execute the migrations in sequential order, inserting the new Player and updating all the Mistery rows with the reference to your new Player.
If your database already contains Mystery objects, then south must know, what value put into player field, because it cannot be blank.
One possible solution:
choose
2. Specify a one-off value to use for existing columns now
and then enter 1. So all of your existing Mystery objects will now point to Player with pk = 1. Then you can change (if needed) this in admin page.