Created
February 26, 2013 09:53
-
-
Save runekaagaard/5037369 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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