<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Chris Pratt // Metaphors Be With You &#187; scripts</title>
	<atom:link href="http://www.chrisdpratt.com/tag/scripts/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.chrisdpratt.com</link>
	<description>Random thoughts on random topics. What? You wanted predictability?</description>
	<lastBuildDate>Fri, 31 Jul 2009 14:58:51 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Django Snippet to Refresh Your Database</title>
		<link>http://www.chrisdpratt.com/2008/02/27/a-django-snippet-to-refresh-your-database/</link>
		<comments>http://www.chrisdpratt.com/2008/02/27/a-django-snippet-to-refresh-your-database/#comments</comments>
		<pubDate>Wed, 27 Feb 2008 18:27:38 +0000</pubDate>
		<dc:creator>chrisdpratt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[scripts]]></category>

		<guid isPermaLink="false">http://www.chrisdpratt.com/2008/02/27/a-django-snippet-to-refresh-your-database/</guid>
		<description><![CDATA[Django doesn&#8217;t have anything remotely close to migrations in Rails. It does have the syncdb management command, but that&#8217;s only good for initial table creation. If you need to add or remove a model attribute at a later point, you&#8217;re pretty much stuck with manual alter table commands to your database.
I&#8217;ve found that I have [...]]]></description>
			<content:encoded><![CDATA[<p>Django doesn&#8217;t have anything remotely close to migrations in Rails. It does have the syncdb management command, but that&#8217;s only good for initial table creation. If you need to add or remove a model attribute at a later point, you&#8217;re pretty much stuck with manual alter table commands to your database.</p>
<p>I&#8217;ve found that I have to do this entirely too often in development, and it becomes increasingly frustrating with frequency. As a result, I&#8217;ve written a little python script to take care of all the grunt work for me.</p>
<h2>Disclaimer</h2>
<p>Now, before I post the code, let me make clear that although I&#8217;ve used this a number of times already, I cannot guarantee that it&#8217;s 100% bug-free. It should definitely only be used on a development database, if for no other reason than should the catastrophic happen, you&#8217;ve only lost dummy data and not real user accounts and such. Also, I don&#8217;t claim to be a python expert. In fact, part of the reason I&#8217;m posting this is that hopefully a few python experts might stumble by and critique my code. Still, all that said, I think it still has benefit for the community, and hopefully it will be a help to some of you.</p>
<h2>Code</h2>
<p>#!/usr/bin/env python</p>
<p>print &#8220;Setting Up Environment&#8230; &#8220;,<br />
try:<br />
    import settings # Assumed to be in the same directory.<br />
except ImportError:<br />
    import sys<br />
    sys.stderr.write(&#8221;Error: Can&#8217;t find the file &#8217;settings.py&#8217; in the directory containing %r.\n(If the file settings.py does indeed exist, it&#8217;s causing an ImportError somehow.)\n&#8221; % __file__)<br />
    sys.exit(1)</p>
<p>from django.core.management import setup_environ, call_command<br />
setup_environ(settings)<br />
print &#8220;Done&#8221;</p>
<p>import sys</p>
<p>print &#8220;Dumping Data&#8230; &#8220;,<br />
sys.stdout = open(&#8217;dumped_data.json&#8217;, &#8216;w&#8217;)<br />
call_command(&#8217;dumpdata&#8217;, format=&#8217;json&#8217;, indent=4)<br />
sys.stdout.close()<br />
sys.stdout = sys.__stdout__<br />
print &#8220;Done&#8221;</p>
<p>print &#8220;Deleting Tables&#8230; &#8220;,<br />
import StringIO<br />
from django.db.models import get_apps<br />
app_labels = [app.__name__.split('.')[-2] for app in get_apps()]<br />
sys.stdout = buffer = StringIO.StringIO()<br />
call_command(&#8217;sqlclear&#8217;, *app_labels)<br />
sys.stdout = sys.__stdout__</p>
<p>queries = buffer.getvalue().split(&#8217;;')[1:-2]</p>
<p>from django.db import connection<br />
cursor = connection.cursor()<br />
for query in queries:<br />
    cursor.execute(query.strip())<br />
print &#8220;Done&#8221;</p>
<p>print &#8220;Synching Database&#8230; &#8221;<br />
#disable the &#8220;create a super user&#8221; question<br />
from django.contrib.auth.management import create_superuser<br />
from django.contrib.auth import models as auth_app<br />
from django.db.models import signals<br />
from django.dispatch import dispatcher<br />
dispatcher.disconnect(create_superuser, sender=auth_app, signal=signals.post_syncdb)</p>
<p>call_command(&#8217;syncdb&#8217;)<br />
print &#8220;Done&#8221;</p>
<p>print &#8220;Loading Back Data&#8230; &#8221;<br />
call_command(&#8217;loaddata&#8217;, &#8216;dumped_data.json&#8217;)<br />
import os<br />
os.remove(&#8217;dumped_data.json&#8217;)<br />
print &#8220;Done&#8221;</p>
<h2>What Does it Do?</h2>
<p>First, the script loads in your project&#8217;s settings.py and sets up the Django environment. If you&#8217;ve ever looked at the code behind manage.py, you&#8217;ll notice I basically ripped that part off. Second, the script uses Django&#8217;s dumpdata management command to save all the current data in the database in a JSON object.</p>
<p>Third, it gets a list of all the currently install apps, and uses Django&#8217;s sqlclear management command to get the database specific delete statements. Essentially, it&#8217;s just emptying out the database. I debated about simply dropping the database and creating a new one, but I wanted this script to be as database agnostic as possible.</p>
<p>Next, it runs Django&#8217;s syncdb management command to recreate the database based on the current state of your models. However, before is does that, it disables the signal responsible for the &#8220;create a superuser&#8221; prompt that Django&#8217;s Auth module gives. Finally, it reloads the data we dumped previously back into the database.</p>
<p>At this point, you should have an exact duplicate of your old database, only with the changes you made to your models implemented.</p>
<h2>How to Use it?</h2>
<p>Save that code in an file in the root of your project (same level as settings.py). I called mine &#8216;refresh_db.py&#8217;. If you&#8217;re on a *nix based platform you&#8217;ll want to give the script execute priveleges, as well (chmod 755). Then, just run it from the command line, whenever you see fit.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.chrisdpratt.com/2008/02/27/a-django-snippet-to-refresh-your-database/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
