'Django models sqlmigrate - too few arguments
Here are my Django models, which have multiple many to many relationships.
class Theme(models.Model):
theme_name = Models.CharField(max_length=20)
theme_ind = Models.CharField(max_length=1)
class Topics(models.Model):
topic_name = Models.CharField(max_length=20)
class Language(models.Model):
lang_name = models.CharField(max_length=10)
class Article(models.Model):
name = Models.CharField(max_length=10)
url = Models.CharField(max_length=50)
lang_id = models.ManyToManyField(Language, related_name='theme')
theme_id = models.OneToOneField(Theme, related_name='theme')
topic_id = models.ManyToManyField(Topics, related_name='topic')
Question: When I run:
python manage.py sqlmigrate polls
I get this error:
manage.py sqlmigrate: error: too few arguements.
Solution 1:[1]
You forgot the prefix of makemigrations command output file.
When you run:
python manage.py makemigrations polls
You will see in output 0001_any_name.py.
Here, 0001 is used in sqlmigrate for creating the database that you forgot to add in your command.
So, write:
python manage.py sqlmigrate polls 0001
Solution 2:[2]
From the docs, sqlmigrate also requires the migration name:
python manage.py sqlmigrate polls <migration_name>
Solution 3:[3]
I just ran across this, my issue: I'm making a lot of changes at once and I need to see all the migrations and I don't have time to go through each file and get the generated sql.
NOTE: The sql is NOT guaranteed to be in order, so if you have a migration that adds a field, and another that populates it, this might export the populating sql first causing your command to crash.
cat <<EOF | ./manage.py shell
from __future__ import print_function
import os
try:
from StringIO import StringIO # for Python 2
except ImportError:
from io import StringIO # for Python 3
from django.core.management import call_command
from django.apps import apps
# Remove all the terminal colors, less parsing later.
os.environ['DJANGO_COLORS'] = 'nocolor'
out = StringIO()
call_command('showmigrations', stdout=out)
# Clean up the line, and remove all applied migrations
work = [line.strip() for line in out.getvalue().split('\n') if not line.startswith(' [X]')]
# Keep looping until we run out of lines.
while work:
app_name = work.pop(0)
while work and work[0].startswith('['):
migration_name = work.pop(0)[4:]
app_path = apps.get_app_config(app_name).module.__file__
# Print the whole path to the migration file that corresponds to this migration
print('--', os.path.abspath(os.path.join(app_path, '../migrations/', '{}.py'.format(migration_name))))
call_command('sqlmigrate', app_name, migration_name[:8])
EOF
This is very similar to the original solution, main difference is that now everything runs inside a single python process, that doesn't have to load up Django N times for every migration, speeding this up tremendously.
Old solution (slow)
It's hard to comment code in bash, so i'll do it here.
- get all the migrations.
- filter all migrations that have been applied.
- get python to give us a nice list of all the migrations that havent been applied format:
<app> <4 digit migration code>\n - use
xargsto get every 2 fields, see above, and pipe it tosqlmigrateto get all the changes. - patience, this is not the fastest.
Code:
./manage.py showmigrations | grep -v [X] | python <(cat <<EOF
from __future__ import print_function # just in case
import sys
work = [line.strip() for line in sys.stdin]
while work:
header = work.pop(0)
while work and work[0].startswith('['):
print(header, work.pop(0)[4:8])
EOF
) | xargs -n 2 ./manage.py sqlmigrate
Solution 4:[4]
sqlmigrate is for printing the sql that will be part of a migration
There should be one more argument, as the error suggests:
sqlmigrate app_label migrationname
See: https://docs.djangoproject.com/en/1.8/ref/django-admin/#django-admin-sqlmigrate
Perhaps you're trying to do something like this:
python manage.py makemigrations polls
python manage.py migrate
Solution 5:[5]
Whenever you create a table or add changes to existing table you need to run 3 commands:
- python manage.py makemigrations app_name
- python manage.py sqlmigrate app_name migration_name
- python manage.py migrate
It seems that you have missed providing the migration name as mentioned in point 2
Solution 6:[6]
You have to run this command:
python manage.py sqlmigrate polls 0001
Solution 7:[7]
to get all migrations in order you could use showmigrations -p
and you could add it to Javier solution for generating all the SQL statement in order
import os
import django
from io import StringIO
from django.core.management import call_command
from django.apps import apps
import re
# Remove all the terminal colors, less parsing later.
os.environ['DJANGO_COLORS'] = 'nocolor'
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')
django.setup()
out = StringIO()
call_command('showmigrations', '-p', stdout=out)
# Clean up the line, and remove all applied migrations
migrations = [line.strip() for line in out.getvalue().split('\n')]
migration_regex = re.compile('^\[[X ]\] ([^.]*).(.*)$')
with open('sql_script.sql', 'w') as out_file:
for migration in migrations:
searched_migration = re.search(migration_regex, migration)
if searched_migration:
app_name = searched_migration.group(1)
migration_name = searched_migration.group(2)
app_path = apps.get_app_config(app_name).module.__file__
call_command('sqlmigrate', app_name, migration_name, stdout=out_file)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 | |
| Solution 4 | user2687058 |
| Solution 5 | Pratik Randad |
| Solution 6 | theUtherSide |
| Solution 7 | Amr Hashem |
