Search code examples
pythondjangoamazon-web-servicesamazon-elastic-beanstalkdjango-migrations

Django migration is not changing database in AWS Elastic Beanstalk


I have deployed my Djnago app using AWS Elastic Beanstalk. I have added some data and everything was working fine. Then I have increased max_length of one of the CharField in model.py. I have deployed the app again using 'eb deploy' command. But it did not increase the field length in database. If I try to add subject_id greater than 10, I get this error: django.db.utils.DataError: value too long for type character varying(10)

Model.py:

class Subject(models.Model):
        #subject_id = models.CharField(max_length=10, blank=True)
        subject_id = models.CharField(max_length=50, blank=True)

0001_initial.py:

#Generated by Django 3.0.4 on 2021-02-18 18:54
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
    initial = True
    dependencies = [
        ('accounts', '0001_initial'),]
    operations = [
        migrations.CreateModel(
            name='Subject',
            fields=[('subject_id', models.CharField(blank=True, max_length=50)),],),]

I have added migration command in .ebextensions/django_build.config file. The 0001_initial.py file inside migration folder shows the changes. But it is not updated in the database(AWS RDS postgresql). I have checked django_migrations table in postgresql database. It's showing the last migration happened when I first created the instance.

I need to change subject_id field length of Subject model in existing database. Any help will be appreciated.

.ebextensions/django_build.config:

container_commands:
  01_create_log_folder:
    command: "mkdir -p log && chown webapp:webapp -R log"

  02_source_env:
    command: "source /etc/profile.d/sh.local"
    leader_only: true  
    
  03_database_migrations:
    command: "source /var/app/venv/*/bin/activate && python3 manage.py makemigrations --noinput && python3 manage.py migrate --noinput && deactivate"
    leader_only: true

django_migrations table:

select * from django_migrations;
 id |       app       |                   name                   |            applied            
----+-----------------+------------------------------------------+-----------------------
 28 | fileupload      | 0001_initial                             | 2021-01-22 11:42:40.726471+00

Solution

  • Since your revised migration has the same name (0001_initial) as the one you've already applied, it is not being executed. You need to either:

    • Create a new migration (0002_new_migration) that alters the fields you created in the first one

    OR

    • First rollback the migration you have and then apply the revised one

    To rollback the migration you have, you'll need to SSH into the ELB instance:

    Login via SSH - check your AWS console for specific instructions
    

    Then run the following to reset the accounts migrations

    source /opt/python/run/venv/bin/activate
    source /opt/python/current/env
    cd /opt/python/current/app
    ./manage.py migrate accounts zero
    

    When you deploy next, you'll be starting the accounts model from scratch and your new migration will run.

    This is no different than when you reverse migrations locally using manage.py and migrate, except you're doing it on your remote instance.