Django makemigrations show no changes detected after table rename in mysql - django

I have a Django application with a My-SQL database. recently I alter the table_name with the help of MySQL query in the MySQL-shell, after this when I run makemigration and migrate command terminal says "No changes detected". how can i resolve this issue and create again this table with help of Django makemigration and migrate?
can I delete a table from MySQL, any possibility will Django create it again?

If you renamed your table outside Django - you will have to tell Django the new table name like so (using the Meta class):
class Model(models.Model):
name = models.CharField(max_length=255)
class Meta:
db_table = 'new_table_name'
To re-create your table using existing model you need to reset migration for that app to zero and then run migration again
python manage.py migrate APP_NAME zero
python manage.py migrate APP_NAME

It's because the migrations table managed by django doesn't reflect the correct db schema since it was already modified outside of django. If you don't have any important data you can do a migration rollback or recreate the table by hand.
The best way to dela with this is to rename your table back to the original name. Then create a blank migration inside your app and recreate the sql commands you did in the shell inside that migration file. That way django can keep track of the database schema.

You should change the name of the table in models.py not in MySQL shell.
From
class MyModel(models.Model):
...
To
class ThisModel(models.Model):
...
Or Create Proxy Model :
class ThisModel(MyModel):
class Meta:
proxy = True
verbose_name = "ThisModel"

Related

How to apply one specific change to database after 'makemigrations' command?

I added a field to one of my models, but in the 'models' folder I have two other python files which have only View models from which I query views in my database. When I run the makemigrations command, the new migrations file that is created includes also adding these view models to my database as tables (which I don't want to). How can I ignore these changes, and only commit the one addition of a field to an actual table on the database.
I think I maybe have to delete the migrations.CreateModel... in the new migrations file and only keep the migrations.addField... , then run the 'migrate' command. I didn't proceed with this because I'm not sure and maybe it will mess up my database in some way.
Thanks in advance to anyone who can help.
when you make a model for database view you must add meta class managed = false and db_table like this:
class MyViewModel(models.Model):
field: models.CharField(max_length=100)
class Meta:
managed = False
db_table = 'database_view_name'
when you write this and run makemigrations a migration generated contains this model but when you run migrate this migration doesnt change anything on database.
you also can create view using migrations in python. see migrations.RunPython for more details

Change unique=True to unique=False from my model field

I have one field in my model with like this name = models.CharField(max_length=100, unique=True) but now that table/model have a lot of data and need to change the True to False but without having to drop the table and créate it again, How can I do that?
Generate the new migration using:
python manage.py makemigrations
The above will detect changes to your model and generate a migration class but no execute any sql yet.
To generate/apply the sql to the db:
python manage.py migrate
If you want to see the sql that will be executed before updating the db do this before migrate:
python sqlmigrate {app_label} {migration_module}
EDIT: The above will rename your table with suffix __old, create a new table and insert the data from the old to the new one, and then drop the original table. So not sure if this is what you want..
Another option would be to use plain sql to achieve what you want:
ALTER TABLE table_name DROP CONSTRAINT constraint_name;
But remember, in order keep your migrations updated for new runs, find the migration class that declares your field as unique and change unique=True to unique=False. If any other servers need to be updated you can run the drop constraint command there too so everything is in sync.
Just change the value to False in the model and then makemigrations and migrate. This will update all items in the DB to the new value. This is if you are using the newer version with South and not using syncdb.

Syncdb error when creating CustomUser

The issue is that I create Custom User:
class CustomUser(AbstractUser):
mobile = models.CharField(max_length=16)
address = models.CharField(max_length=100)
And in settings.py write this:AUTH_USER_MODEL = 'login.CustomUser'
And when I run manage.py syncdb for the first time(when db doesn't contains any tables), it throws an error: django.db.utils.ProgrammingError: relation "auth_group" does not exist
But when I run manage.py syncdb when db with tables already exist, then it's okay, just create additional tables. What's wrong to run it when db doesn't contain tables?
Try this
Create a migration directory in the directory of the app containing your custom user model.
Create an empty __init__.py file inside the migration directory.
Execute ./manage.py makemigrations.
Execute ./manage.py migrate.
I think when you use a custom user model, you need to create migrations. Besides, syncdb is already deprecated and will be removed in Django 1.9 so it's better to start using the ./manage.py migrate command.
As the error says, Your CustomUser table has relation with auth_group table, so unless that table is created or exists, you cannot create this new table in db.
When you say 'db with tables already exist, then it's okay', did You create the tables manually or included admin app in your INSTALLED_APPS?
Because if u include admin app, it will automatically create the auth_group table, so you will not see that issue

Database error in creating blog using django

Am trying to create simple blog using django.
At first,i created database with the command
python manage.py syncdb
when i try to save blog post,i get the following error
DatabaseError: table blog_app_post has no column named body
models.py code :
from django.db import models
from taggit.managers import TaggableManager
class Post(models.Model):
title = models.CharField(max_length=255)
body = models.TextField()
created = models.DateTimeField()
tags = TaggableManager()
def __unicode__(self):
return self.title
but the column named body is actually created in the Db.
BEGIN;
CREATE TABLE "blog_app_post" (
"id" integer NOT NULL PRIMARY KEY,
"title" varchar(255) NOT NULL,
"body" text NOT NULL,
"created" datetime NOT NULL
)
what does this error mean and anyone would propose a solution for this?
This is probably because you changed the structure of your posts data structure. What you need to do now is delete the schema for your previous table and paste in the new one.
You can avoid problems like this by using migration managers like south.
So, in order to solve this, run manage.py sql <app_name>, then you simply copy the latest SQL table on the list, the first one that is printed. Then you simply maange.py dbshell and then just paste and run the SQL.
How do you say that it's created, you checking it using python manage.py sqlall?
Did you add field body after running syncdb initially. In that case you will have to use a migration.

using south datamigration to change value in old records

Previously I had a django model like this
class Review(models.Model):
reviewdate=models.DateField(default=date.today)
description=models.TextField()
author=models.ForeignKey(User,null=True)
I have some 500 records of Review in db.
I added a field to model
from django.core.validators import MinValueValidator,MaxValueValidator
class Review(models.Model):
reviewdate=models.DateField(default=date.today)
description=models.TextField()
author=models.ForeignKey(User,null=True)
rating= models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(10)], default=5, help_text='integers 1 to 10')
I ran python manage.py schemamigration myapp --auto successfully ,which created a 0002_auto__add_field_review_rating.py file
Now, I need to do the datamigration for the existing records in db. Do I have to run
python manage.py datamigration myapp somechanges
and then implement the functions in the created somechanges.py ? Since I have already defined in the new field difficulty a default value of 5, will that not be taken when migrate command is run? Do I have to explicitly set it in the somechanges.py functions?
You do not need to do a data migration for this case. As you have specified a default for your new field, that will be used when you apply the schema migration.
Use the following command to apply the migration:
./manage.py migrate myapp
See the advanced changes South tutorial for more information on default values for new fields.