0

I am writing script supporting my Django project development. First I thought of using bash for this purpose but due to lack of enough knowledge and total lack of time I decided to write something using argparse and running system commands using subprocess.

Everything went ok until I had to run

./manage.py migrate

I do it by running:

import subprocess
...
subprocess.Popen("python {} migrate".format(absolute_path_to_manage_py).split())

The output seems to look ok:

Operations to perform:
Apply all migrations: sessions, admin, auth, contenttypes, accounts, pcb
Running migrations:
Rendering model states... DONE
Applying contenttypes.0001_initial... OK
...
Applying sessions.0001_initial... OK    

And it stops suddenly, but script is still active (it's still running) and what's worse when I run django app I get a message that I still have some unapplied migrations.

I think I don't know something about running system commands from Python or something related to django migrations.

Any hint how I could overcome this?

hebius
  • 133
  • 1
  • 14
  • POpen is unblocking function. You should pass PIPEs or use blocking function. You can try subprocess.check_call https://docs.python.org/2/library/subprocess.html#module-subprocess – Denis Feb 04 '16 at 08:57
  • try `subprocess.check_call([sys.executable, 'manage.py', 'migrate'], cwd=os.path.dirname(absolute_path_to_manage_py))`, to run `manage.py` from its directory and to wait for it to finish (raising an exception on non-zero exit status) – jfs Feb 04 '16 at 14:17

2 Answers2

1

From the subprocess docs:

The recommended way to launch subprocesses is to use the following convenience functions. For more advanced use cases when these do not meet your needs, use the underlying Popen interface.

You could use subprocess.call(), which waits for the command to complete:

returncode = subprocess.call(["python", absolute_path_to_manage_py, "migrate"])
Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
1

Rather than using a subprocess, you can call the management command directly using call_command:

from django.core.management import call_command

call_command('migrate')
knbk
  • 52,111
  • 9
  • 124
  • 122