# Author: limodou (limodou@gmail.com) # # This tool is used for dump and reload data from and into database # You can see the help info through: # # python db_dump.py -h # # For now, it only support .py format, so the output result will # be saved as python source code, and you can import it. # # Version 2.2 2007-11-01 # * improve postgresql sequence field process, thanks oyvind.saltvik@gmail.com and Matthew Wensing # * add errorquit option in command line # # Version 2.1 2007-09-18 # * add Time type support # # Version 2.0 2007-09-11 # * refact, and add aoto reset postgres sequence, thanks Eric SIMORRE # # Version 1.9 2007-09-02 (Merge from RichardH) # * Adds try-except to catch the changes in db.backend refactoring in # svn version. So db_dump.py can support old version except trunk. # # Version 1.8 2007-08-30 # * Fix backend.quote_name to backend.DatabaseOperations().quote_name # Thanks to richardh # # Version 1.7 2007-05-28 # * keep up with the change of GenericRel, so you can use db_dump.py # in trunk and version before 0.97 # # Version 1.6 2007-04-09 # * Add float support # # Version 1.5 2007-02-08 # * If the filename is not exists, then skip it # # Version 1.4 2007-01-21 # * support mysql # # Version 1.3 2007-01-20 # * change the output format of data file, and improve the process # effective of dumpping and loading # # Version 1.2 2007-01-20 # * change dumpdb to use model info but not cursor.description, # because some database backend does not support cursor.description # # Version 1.1 2007-01-19 # * if no arguments after db_dump.py, then it'll show help infomation # # Version 1.0 2007-01-18 # import os, sys import datetime import decimal from optparse import OptionParser quote_flag = None def _get_table_order(app_labels): from django.db.models import get_app, get_apps, get_models from django.db.models import ForeignKey, OneToOneField if not app_labels: app_list = get_apps() else: app_list = [get_app(app_label) for app_label in app_labels] models = {} for app in app_list: for model in get_models(app): models[model._meta.db_table] = model s = [] rules = [] def order(s, rule): a, b = rule try: i = s.index(a) try: j = s.index(b) if j>f, 'table = %r' % table print >>f, 'fields = %r' % fields print >>f, '#default item format: "fieldname":("type", "value")' print >>f, 'default = {}' print >>f, 'records = [' i = 0 for t in result: print >>f, repr(t) i += 1 print >>f, ']' if options.verbose: print '(Total %d records)\n' % i if not options.stdout: f.close() def quote_name(s): from django.db import backend if quote_flag == 'old': return backend.quote_name(s) else: return backend.DatabaseOperations().quote_name(s) #thanks for Matthew Wensin def setSequence(cursor, model): from django.conf import settings from django.db.models import AutoField # postgresql: reset sequence if settings.DATABASE_ENGINE in ('postgresql_psycopg2', 'postgresql'): autofields = [field for field in model._meta.fields if isinstance(field, AutoField)] for f in autofields: seq = quote_name('%s_%s_seq' % (model._meta.db_table, f.name)) cursor.execute("SELECT nextval('%s');" % seq) nb = cursor.fetchall()[0][0] if nb: cursor.execute('ALTER SEQUENCE %s RESTART WITH %d;' % (seq, nb)) def get_usage(): usage = """ %prog [options] action [applist]: action: dump load """ return usage def execute_from_command_line(argv=None): # Use sys.argv if we've not passed in a custom argv if argv is None: argv = sys.argv # Parse the command-line arguments. optparse handles the dirty work. parser = OptionParser(usage=get_usage()) parser.add_option('--settings', help='Python path to settings module, e.g. "myproject.settings.main". If this isn\'t provided, the DJANGO_SETTINGS_MODULE environment variable will be used.') parser.add_option('-d', '--dir', help='Output/Input directory.', default="datadir", dest="datadir") # parser.add_option('-f', '--format', help='Data format(json, xml, python).', type="choice", # choices=['json', 'xml', 'python'], default='json') parser.add_option('-v', '--verbose', help='Verbose mode', action='store_true') parser.add_option('-s', '--stdout', help='Output the data to stdout', action='store_true') parser.add_option('-r', '--remain', help='Remain the records of the tables, default will delete all the records. Only used for loading.', action='store_true') parser.add_option('-e', '--errorquit', help='If there are errors occured, then exit the program.', action='store_true') options, args = parser.parse_args(argv[1:]) if len(args) == 0: parser.print_help() sys.exit(0) action = args[0] apps = args[1:] if options.settings: os.environ['DJANGO_SETTINGS_MODULE'] = options.settings else: from django.core.management import setup_environ try: import settings except ImportError: print "You don't appear to have a settings file in this directory!" print "Please run this from inside a project directory" sys.exit() setup_environ(settings) global quote_flag import django.db try: # Earlier Django versions. django.db.backend.quote_name quote_flag = 'old' except AttributeError: # Django after backend refactoring. quote_flag = 'new' if action == 'dump': dumpdb(apps, 'py', options) elif action == 'load': loaddb(apps, 'py', options) else: parser.print_help() if __name__ == '__main__': execute_from_command_line()