So something that has been bugging me since the recent release of nashvegas was the lack of handling errors in migration scripts.
There were several issues impeding me being able to handle errant scripts
gracefully, by which I mean reporting the error via a sys.exit()
call.
I was sub-shelling to manage.py dbshell
where I would PIPE
the contents of
the script to stdin
. Turns out that dbshell
executes the database client
process via os.execvp
which as the Python document
states:
These functions all execute a new program, replacing the current process; they do not return.
So, obviously, I was not going to get a return code from the underlying call, that I might check and take evasive action.
Because I was getting to the database client indirectly through dbshell
, I
was unable to control things like setting flags or variables to control the
behavior of the database client. So, even if I were to somehow get around the
first problem of os.execvp
being used, I still would not be able to set the
necessary flags needed to get the client to behave how I wanted it to.
Therefore, I decided that I’d just copy the argument building from each of the
django.db.backends.*.client
modules and execute the client commands
directly. This would also give me the ability to fine tune the command line
parameters as I needed.
I decided to focus on postgresql because it’s my
database of choice these days. I learned tonight that if I pass the command
line parameter \--set ON_ERROR_STOP=TRUE
, that the execution of sql commands
stops on error and exits the client with a return code of 3.
So, now, with nashvegas 0.2a1.dev3
and your database set to postgresql, you can rely on errors in migration
scripts to abort, given you the ability to fix without recording the migration
in the Migration
model.
I haven’t attempted to figure out how all the other clients work, though they
are supported with the same options as found in django.db.backends
. So if by
default they exit with error status codes then they’ll work like mentioned
above. However, if they are require additional command line arguments like
postgresql did to exhibit similar behavior, then I ask that someone submit a
patch and I’ll gladly incorporate it.