Skip to content

Instantly share code, notes, and snippets.

@runekaagaard
Created February 26, 2013 09:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save runekaagaard/5037369 to your computer and use it in GitHub Desktop.
Save runekaagaard/5037369 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
# encoding=utf-8
import sys
import os
from pprint import pprint
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "qa.settings")
from django.contrib.contenttypes.models import ContentType
# Output utf-8 on the command line, why is this buggy on my box?
reload(sys)
sys.setdefaultencoding("utf-8")
"""
Script to copy all data in a django project from one database connection to
another. m2m relations are not supported, unless they are explicitly defined
with through. Not very battletested.
Change settings with all caps to reflect your setup.
Inspired by http://macrotoma.blogspot.dk/2012/10/solved-move-django-from-sqlite-to-mysql.html
Replace step 6. with:
1. Edit FROM and TO in this script
2. run: python copy_db_connection.py collection_info
3. Change TABLES in this script based on the output of the previous command
4. run: python copy_db_connection.py copy_data
5. If errors occur goto 3.
6. Verify everything went ok
"""
# The name of the DB connection to copy from.
FROM = 'default'
# The name of the DB connection to copy to.
TO = 'slave'
# An ordered list of the tables outputted with the "collect_info" command.
# The ordering is necessary to avoid foreign key constraint errors.
TABLES = [
(u'user', u'auth', u'user'),
(u'group', u'auth', u'group'),
(u'site', u'sites', u'site'),
(u'session', u'sessions', u'session'),
(u'content type', u'contenttypes', u'contenttype'),
(u'log entry', u'admin', u'logentry'),
(u'permission', u'auth', u'permission'),
(u'api access', u'tastypie', u'apiaccess'),
(u'api key', u'tastypie', u'apikey'),
(u'migration history', u'south', u'migrationhistory'),
(u'Samling af spørgsmålsamlinger', u'questions', u'questioncollectionscollection'),
(u'Spørgsmålsamling', u'questions', u'questionscollection'),
(u'Spørgsmål', u'questions', u'question'),
(u'Spørgsmål til denne spørgsmålssamling', u'questions', u'questionscollectionquestion'),
(u'Valgmulighed', u'questions', u'option'),
(u'Samling af svar', u'answers', u'answerscollection'),
(u'Svar', u'answers', u'answer'),
]
def get_model_classes():
"""
Returns a list of model classes defined in TABLES.
"""
models = []
for table in TABLES:
content_type = ContentType.objects.get(app_label=table[1],
model=table[2])
model_class = content_type.model_class()
assert model_class is not None, "Model class not found. Is it's app enabled in settings.py?"
models.append(model_class)
return models
def collect_info():
"""
Outputs a list of all tables.
"""
tables = []
for obj in ContentType.objects.all():
tables.append((obj.name, obj.app_label, obj.model))
pprint(tables)
def copy_data():
"""
First truncates all data, then copies data from the FROM db connection to
the TO db connection with the tables defined in TABLES.
"""
for model_class in get_model_classes():
print model_class
model_class.objects.all().using(TO).delete()
# Copy data.
for model_class in get_model_classes():
for obj in model_class.objects.all().distinct():
print "Saving: ", obj
obj.save(using=TO)
if __name__ == "__main__":
ERR_MSG = "Allowed commands are 'collect_info' and 'copy_data'"
try:
if sys.argv[1] == 'collect_info':
collect_info()
elif sys.argv[1] == 'copy_data':
copy_data()
else:
raise Exception(ERR_MSG)
except IndexError:
raise Exception(ERR_MSG)
@evoxco
Copy link

evoxco commented Sep 22, 2014

With a few teaks works great.
Also small typo
2. run: python copy_db_connection.py collection_info
should be
2. run: python copy_db_connection.py collect_info

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment