mirror of
https://github.com/django/django.git
synced 2025-11-07 07:15:35 +00:00
Fixed #1142 -- Added multiple database support.
This monster of a patch is the result of Alex Gaynor's 2009 Google Summer of Code project. Congratulations to Alex for a job well done. Big thanks also go to: * Justin Bronn for keeping GIS in line with the changes, * Karen Tracey and Jani Tiainen for their help testing Oracle support * Brett Hoerner, Jon Loyens, and Craig Kimmerer for their feedback. * Malcolm Treddinick for his guidance during the GSoC submission process. * Simon Willison for driving the original design process * Cal Henderson for complaining about ponies he wanted. ... and everyone else too numerous to mention that helped to bring this feature into fruition. git-svn-id: http://code.djangoproject.com/svn/django/trunk@11952 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -1,14 +1,25 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import LabelCommand
|
||||
from django.db import connections, transaction, models, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(LabelCommand):
|
||||
help = "Creates the table needed to use the SQL cache backend."
|
||||
args = "<tablename>"
|
||||
label = 'tablename'
|
||||
|
||||
option_list = LabelCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database onto '
|
||||
'which the cache table will be installed. '
|
||||
'Defaults to the "default" database.'),
|
||||
)
|
||||
|
||||
requires_model_validation = False
|
||||
|
||||
def handle_label(self, tablename, **options):
|
||||
from django.db import connection, transaction, models
|
||||
alias = options.get('database', DEFAULT_DB_ALIAS)
|
||||
connection = connections[alias]
|
||||
fields = (
|
||||
# "key" is a reserved word in MySQL, so use "cache_key" instead.
|
||||
models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True),
|
||||
@@ -19,7 +30,7 @@ class Command(LabelCommand):
|
||||
index_output = []
|
||||
qn = connection.ops.quote_name
|
||||
for f in fields:
|
||||
field_output = [qn(f.name), f.db_type()]
|
||||
field_output = [qn(f.name), f.db_type(connection=connection)]
|
||||
field_output.append("%sNULL" % (not f.null and "NOT " or ""))
|
||||
if f.primary_key:
|
||||
field_output.append("PRIMARY KEY")
|
||||
@@ -39,4 +50,4 @@ class Command(LabelCommand):
|
||||
curs.execute("\n".join(full_statement))
|
||||
for statement in index_output:
|
||||
curs.execute(statement)
|
||||
transaction.commit_unless_managed()
|
||||
transaction.commit_unless_managed(using=alias)
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
from django.core.management.base import NoArgsCommand, CommandError
|
||||
from optparse import make_option
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
help = "Runs the command-line client for the current DATABASE_ENGINE."
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = ("Runs the command-line client for specified database, or the "
|
||||
"default database if none is provided.")
|
||||
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database onto which to '
|
||||
'open a shell. Defaults to the "default" database.'),
|
||||
)
|
||||
|
||||
requires_model_validation = False
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
from django.db import connection
|
||||
def handle(self, **options):
|
||||
connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
|
||||
try:
|
||||
connection.client.runshell()
|
||||
except OSError:
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from django.core.exceptions import ImproperlyConfigured
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
from django.core import serializers
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
from django.utils.datastructures import SortedDict
|
||||
|
||||
from optparse import make_option
|
||||
@@ -11,6 +12,9 @@ class Command(BaseCommand):
|
||||
help='Specifies the output serialization format for fixtures.'),
|
||||
make_option('--indent', default=None, dest='indent', type='int',
|
||||
help='Specifies the indent level to use when pretty-printing output'),
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
|
||||
'fixtures into. Defaults to the "default" database.'),
|
||||
make_option('-e', '--exclude', dest='exclude',action='append', default=[],
|
||||
help='App to exclude (use multiple --exclude to exclude multiple apps).'),
|
||||
make_option('-n', '--natural', action='store_true', dest='use_natural_keys', default=False,
|
||||
@@ -24,14 +28,16 @@ class Command(BaseCommand):
|
||||
|
||||
format = options.get('format','json')
|
||||
indent = options.get('indent',None)
|
||||
using = options.get('database', DEFAULT_DB_ALIAS)
|
||||
connection = connections[using]
|
||||
exclude = options.get('exclude',[])
|
||||
show_traceback = options.get('traceback', False)
|
||||
use_natural_keys = options.get('use_natural_keys', False)
|
||||
|
||||
excluded_apps = [get_app(app_label) for app_label in exclude]
|
||||
excluded_apps = set(get_app(app_label) for app_label in exclude)
|
||||
|
||||
if len(app_labels) == 0:
|
||||
app_list = SortedDict([(app, None) for app in get_apps() if app not in excluded_apps])
|
||||
app_list = SortedDict((app, None) for app in get_apps() if app not in excluded_apps)
|
||||
else:
|
||||
app_list = SortedDict()
|
||||
for label in app_labels:
|
||||
@@ -74,7 +80,7 @@ class Command(BaseCommand):
|
||||
objects = []
|
||||
for model in sort_dependencies(app_list.items()):
|
||||
if not model._meta.proxy:
|
||||
objects.extend(model._default_manager.all())
|
||||
objects.extend(model._default_manager.using(using).all())
|
||||
|
||||
try:
|
||||
return serializers.serialize(format, objects, indent=indent,
|
||||
@@ -137,7 +143,7 @@ def sort_dependencies(app_list):
|
||||
changed = False
|
||||
while model_dependencies:
|
||||
model, deps = model_dependencies.pop()
|
||||
|
||||
|
||||
# If all of the models in the dependency list are either already
|
||||
# on the final model list, or not on the original serialization list,
|
||||
# then we've found another model with all it's dependencies satisfied.
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import connections, transaction, models, DEFAULT_DB_ALIAS
|
||||
from django.core.management import call_command
|
||||
from django.core.management.base import NoArgsCommand, CommandError
|
||||
from django.core.management.color import no_style
|
||||
from django.core.management.sql import sql_flush, emit_post_sync_signal
|
||||
from django.utils.importlib import import_module
|
||||
from optparse import make_option
|
||||
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
option_list = NoArgsCommand.option_list + (
|
||||
make_option('--noinput', action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.'),
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to flush. '
|
||||
'Defaults to the "default" database.'),
|
||||
)
|
||||
help = "Executes ``sqlflush`` on the current database."
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
from django.conf import settings
|
||||
from django.db import connection, transaction, models
|
||||
from django.core.management.sql import sql_flush, emit_post_sync_signal
|
||||
|
||||
db = options.get('database', DEFAULT_DB_ALIAS)
|
||||
connection = connections[db]
|
||||
verbosity = int(options.get('verbosity', 1))
|
||||
interactive = options.get('interactive')
|
||||
|
||||
@@ -28,7 +36,7 @@ class Command(NoArgsCommand):
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
sql_list = sql_flush(self.style, only_django=True)
|
||||
sql_list = sql_flush(self.style, connection, only_django=True)
|
||||
|
||||
if interactive:
|
||||
confirm = raw_input("""You have requested a flush of the database.
|
||||
@@ -36,7 +44,7 @@ This will IRREVERSIBLY DESTROY all data currently in the %r database,
|
||||
and return each table to the state it was in after syncdb.
|
||||
Are you sure you want to do this?
|
||||
|
||||
Type 'yes' to continue, or 'no' to cancel: """ % settings.DATABASE_NAME)
|
||||
Type 'yes' to continue, or 'no' to cancel: """ % connection.settings_dict['NAME'])
|
||||
else:
|
||||
confirm = 'yes'
|
||||
|
||||
@@ -46,23 +54,24 @@ Are you sure you want to do this?
|
||||
for sql in sql_list:
|
||||
cursor.execute(sql)
|
||||
except Exception, e:
|
||||
transaction.rollback_unless_managed()
|
||||
transaction.rollback_unless_managed(using=db)
|
||||
raise CommandError("""Database %s couldn't be flushed. Possible reasons:
|
||||
* The database isn't running or isn't configured correctly.
|
||||
* At least one of the expected database tables doesn't exist.
|
||||
* The SQL was invalid.
|
||||
Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.
|
||||
The full error: %s""" % (settings.DATABASE_NAME, e))
|
||||
transaction.commit_unless_managed()
|
||||
* The database isn't running or isn't configured correctly.
|
||||
* At least one of the expected database tables doesn't exist.
|
||||
* The SQL was invalid.
|
||||
Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run.
|
||||
The full error: %s""" % (connection.settings_dict['NAME'], e))
|
||||
transaction.commit_unless_managed(using=db)
|
||||
|
||||
# Emit the post sync signal. This allows individual
|
||||
# applications to respond as if the database had been
|
||||
# sync'd from scratch.
|
||||
emit_post_sync_signal(models.get_models(), verbosity, interactive)
|
||||
emit_post_sync_signal(models.get_models(), verbosity, interactive, db)
|
||||
|
||||
# Reinstall the initial_data fixture.
|
||||
from django.core.management import call_command
|
||||
call_command('loaddata', 'initial_data', **options)
|
||||
kwargs = options.copy()
|
||||
kwargs['database'] = db
|
||||
call_command('loaddata', 'initial_data', **kwargs)
|
||||
|
||||
else:
|
||||
print "Flush cancelled."
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
import keyword
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import NoArgsCommand, CommandError
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
help = "Introspects the database tables in the given database and outputs a Django model module."
|
||||
|
||||
option_list = NoArgsCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to '
|
||||
'introspect. Defaults to using the "default" database.'),
|
||||
)
|
||||
|
||||
requires_model_validation = False
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
try:
|
||||
for line in self.handle_inspection():
|
||||
for line in self.handle_inspection(options):
|
||||
print line
|
||||
except NotImplementedError:
|
||||
raise CommandError("Database inspection isn't supported for the currently selected database backend.")
|
||||
|
||||
def handle_inspection(self):
|
||||
from django.db import connection
|
||||
import keyword
|
||||
def handle_inspection(self, options):
|
||||
connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
|
||||
|
||||
table2model = lambda table_name: table_name.title().replace('_', '').replace(' ', '').replace('-', '')
|
||||
|
||||
|
||||
@@ -4,8 +4,13 @@ import gzip
|
||||
import zipfile
|
||||
from optparse import make_option
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import serializers
|
||||
from django.core.management.base import BaseCommand
|
||||
from django.core.management.color import no_style
|
||||
from django.db import connections, transaction, DEFAULT_DB_ALIAS
|
||||
from django.db.models import get_apps
|
||||
from django.utils.itercompat import product
|
||||
|
||||
try:
|
||||
set
|
||||
@@ -22,12 +27,19 @@ class Command(BaseCommand):
|
||||
help = 'Installs the named fixture(s) in the database.'
|
||||
args = "fixture [fixture ...]"
|
||||
|
||||
def handle(self, *fixture_labels, **options):
|
||||
from django.db.models import get_apps
|
||||
from django.core import serializers
|
||||
from django.db import connection, transaction
|
||||
from django.conf import settings
|
||||
option_list = BaseCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load '
|
||||
'fixtures into. Defaults to the "default" database.'),
|
||||
make_option('-e', '--exclude', dest='exclude',action='append', default=[],
|
||||
help='App to exclude (use multiple --exclude to exclude multiple apps).'),
|
||||
)
|
||||
|
||||
def handle(self, *fixture_labels, **options):
|
||||
using = options.get('database', DEFAULT_DB_ALIAS)
|
||||
excluded_apps = options.get('exclude', [])
|
||||
|
||||
connection = connections[using]
|
||||
self.style = no_style()
|
||||
|
||||
verbosity = int(options.get('verbosity', 1))
|
||||
@@ -56,9 +68,9 @@ class Command(BaseCommand):
|
||||
# Start transaction management. All fixtures are installed in a
|
||||
# single transaction to ensure that all references are resolved.
|
||||
if commit:
|
||||
transaction.commit_unless_managed()
|
||||
transaction.enter_transaction_management()
|
||||
transaction.managed(True)
|
||||
transaction.commit_unless_managed(using=using)
|
||||
transaction.enter_transaction_management(using=using)
|
||||
transaction.managed(True, using=using)
|
||||
|
||||
class SingleZipReader(zipfile.ZipFile):
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -113,8 +125,8 @@ class Command(BaseCommand):
|
||||
sys.stderr.write(
|
||||
self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." %
|
||||
(fixture_name, format)))
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
transaction.rollback(using=using)
|
||||
transaction.leave_transaction_management(using=using)
|
||||
return
|
||||
|
||||
if os.path.isabs(fixture_name):
|
||||
@@ -127,73 +139,75 @@ class Command(BaseCommand):
|
||||
print "Checking %s for fixtures..." % humanize(fixture_dir)
|
||||
|
||||
label_found = False
|
||||
for format in formats:
|
||||
for compression_format in compression_formats:
|
||||
if compression_format:
|
||||
file_name = '.'.join([fixture_name, format,
|
||||
compression_format])
|
||||
else:
|
||||
file_name = '.'.join([fixture_name, format])
|
||||
|
||||
if verbosity > 1:
|
||||
print "Trying %s for %s fixture '%s'..." % \
|
||||
(humanize(fixture_dir), file_name, fixture_name)
|
||||
full_path = os.path.join(fixture_dir, file_name)
|
||||
open_method = compression_types[compression_format]
|
||||
try:
|
||||
fixture = open_method(full_path, 'r')
|
||||
if label_found:
|
||||
fixture.close()
|
||||
print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." %
|
||||
(fixture_name, humanize(fixture_dir)))
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
return
|
||||
else:
|
||||
fixture_count += 1
|
||||
objects_in_fixture = 0
|
||||
if verbosity > 0:
|
||||
print "Installing %s fixture '%s' from %s." % \
|
||||
(format, fixture_name, humanize(fixture_dir))
|
||||
try:
|
||||
objects = serializers.deserialize(format, fixture)
|
||||
for obj in objects:
|
||||
for combo in product([using, None], formats, compression_formats):
|
||||
database, format, compression_format = combo
|
||||
file_name = '.'.join(
|
||||
p for p in [
|
||||
fixture_name, database, format, compression_format
|
||||
]
|
||||
if p
|
||||
)
|
||||
|
||||
if verbosity > 1:
|
||||
print "Trying %s for %s fixture '%s'..." % \
|
||||
(humanize(fixture_dir), file_name, fixture_name)
|
||||
full_path = os.path.join(fixture_dir, file_name)
|
||||
open_method = compression_types[compression_format]
|
||||
try:
|
||||
fixture = open_method(full_path, 'r')
|
||||
if label_found:
|
||||
fixture.close()
|
||||
print self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting." %
|
||||
(fixture_name, humanize(fixture_dir)))
|
||||
transaction.rollback(using=using)
|
||||
transaction.leave_transaction_management(using=using)
|
||||
return
|
||||
else:
|
||||
fixture_count += 1
|
||||
objects_in_fixture = 0
|
||||
if verbosity > 0:
|
||||
print "Installing %s fixture '%s' from %s." % \
|
||||
(format, fixture_name, humanize(fixture_dir))
|
||||
try:
|
||||
objects = serializers.deserialize(format, fixture, using=using)
|
||||
for obj in objects:
|
||||
if obj.object._meta.app_label not in excluded_apps:
|
||||
objects_in_fixture += 1
|
||||
models.add(obj.object.__class__)
|
||||
obj.save()
|
||||
object_count += objects_in_fixture
|
||||
label_found = True
|
||||
except (SystemExit, KeyboardInterrupt):
|
||||
raise
|
||||
except Exception:
|
||||
import traceback
|
||||
fixture.close()
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
if show_traceback:
|
||||
traceback.print_exc()
|
||||
else:
|
||||
sys.stderr.write(
|
||||
self.style.ERROR("Problem installing fixture '%s': %s\n" %
|
||||
(full_path, ''.join(traceback.format_exception(sys.exc_type,
|
||||
sys.exc_value, sys.exc_traceback)))))
|
||||
return
|
||||
obj.save(using=using)
|
||||
object_count += objects_in_fixture
|
||||
label_found = True
|
||||
except (SystemExit, KeyboardInterrupt):
|
||||
raise
|
||||
except Exception:
|
||||
import traceback
|
||||
fixture.close()
|
||||
|
||||
# If the fixture we loaded contains 0 objects, assume that an
|
||||
# error was encountered during fixture loading.
|
||||
if objects_in_fixture == 0:
|
||||
transaction.rollback(using=using)
|
||||
transaction.leave_transaction_management(using=using)
|
||||
if show_traceback:
|
||||
traceback.print_exc()
|
||||
else:
|
||||
sys.stderr.write(
|
||||
self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" %
|
||||
(fixture_name)))
|
||||
transaction.rollback()
|
||||
transaction.leave_transaction_management()
|
||||
return
|
||||
self.style.ERROR("Problem installing fixture '%s': %s\n" %
|
||||
(full_path, ''.join(traceback.format_exception(sys.exc_type,
|
||||
sys.exc_value, sys.exc_traceback)))))
|
||||
return
|
||||
fixture.close()
|
||||
|
||||
except Exception, e:
|
||||
if verbosity > 1:
|
||||
print "No %s fixture '%s' in %s." % \
|
||||
(format, fixture_name, humanize(fixture_dir))
|
||||
# If the fixture we loaded contains 0 objects, assume that an
|
||||
# error was encountered during fixture loading.
|
||||
if objects_in_fixture == 0:
|
||||
sys.stderr.write(
|
||||
self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)" %
|
||||
(fixture_name)))
|
||||
transaction.rollback(using=using)
|
||||
transaction.leave_transaction_management(using=using)
|
||||
return
|
||||
|
||||
except Exception, e:
|
||||
if verbosity > 1:
|
||||
print "No %s fixture '%s' in %s." % \
|
||||
(format, fixture_name, humanize(fixture_dir))
|
||||
|
||||
# If we found even one object in a fixture, we need to reset the
|
||||
# database sequences.
|
||||
@@ -206,8 +220,8 @@ class Command(BaseCommand):
|
||||
cursor.execute(line)
|
||||
|
||||
if commit:
|
||||
transaction.commit()
|
||||
transaction.leave_transaction_management()
|
||||
transaction.commit(using=using)
|
||||
transaction.leave_transaction_management(using=using)
|
||||
|
||||
if object_count == 0:
|
||||
if verbosity > 1:
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.management.base import AppCommand, CommandError
|
||||
from django.core.management.color import no_style
|
||||
from optparse import make_option
|
||||
from django.core.management.sql import sql_reset
|
||||
from django.db import connections, transaction, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--noinput', action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.'),
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to reset. '
|
||||
'Defaults to the "default" database.'),
|
||||
)
|
||||
help = "Executes ``sqlreset`` for the given app(s) in the current database."
|
||||
args = '[appname ...]'
|
||||
@@ -13,15 +20,13 @@ class Command(AppCommand):
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.db import connection, transaction
|
||||
from django.conf import settings
|
||||
from django.core.management.sql import sql_reset
|
||||
using = options.get('database', DEFAULT_DB_ALIAS)
|
||||
connection = connections[using]
|
||||
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
|
||||
self.style = no_style()
|
||||
|
||||
sql_list = sql_reset(app, self.style)
|
||||
sql_list = sql_reset(app, self.style, connection)
|
||||
|
||||
if options.get('interactive'):
|
||||
confirm = raw_input("""
|
||||
@@ -30,7 +35,7 @@ This will IRREVERSIBLY DESTROY any data for
|
||||
the "%s" application in the database "%s".
|
||||
Are you sure you want to do this?
|
||||
|
||||
Type 'yes' to continue, or 'no' to cancel: """ % (app_name, settings.DATABASE_NAME))
|
||||
Type 'yes' to continue, or 'no' to cancel: """ % (app_name, connection.settings_dict['NAME']))
|
||||
else:
|
||||
confirm = 'yes'
|
||||
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import AppCommand
|
||||
from django.core.management.sql import sql_create
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
help = "Prints the CREATE TABLE SQL statements for the given app name(s)."
|
||||
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.core.management.sql import sql_create
|
||||
return u'\n'.join(sql_create(app, self.style)).encode('utf-8')
|
||||
return u'\n'.join(sql_create(app, self.style, connections[options.get('database', DEFAULT_DB_ALIAS)])).encode('utf-8')
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import AppCommand
|
||||
from django.core.management.sql import sql_all
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
help = "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s)."
|
||||
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.core.management.sql import sql_all
|
||||
return u'\n'.join(sql_all(app, self.style)).encode('utf-8')
|
||||
return u'\n'.join(sql_all(app, self.style, connections[options.get('database', DEFAULT_DB_ALIAS)])).encode('utf-8')
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import AppCommand
|
||||
from django.core.management.sql import sql_delete
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
help = "Prints the DROP TABLE SQL statements for the given app name(s)."
|
||||
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.core.management.sql import sql_delete
|
||||
return u'\n'.join(sql_delete(app, self.style)).encode('utf-8')
|
||||
return u'\n'.join(sql_delete(app, self.style, connections[options.get('database', DEFAULT_DB_ALIAS)])).encode('utf-8')
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import AppCommand
|
||||
from django.core.management.sql import sql_custom
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
help = "Prints the custom table modifying SQL statements for the given app name(s)."
|
||||
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.core.management.sql import sql_custom
|
||||
return u'\n'.join(sql_custom(app, self.style)).encode('utf-8')
|
||||
return u'\n'.join(sql_custom(app, self.style, connections[options.get('database', DEFAULT_DB_ALIAS)])).encode('utf-8')
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from django.core.management.sql import sql_flush
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
help = "Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed."
|
||||
|
||||
option_list = NoArgsCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
from django.core.management.sql import sql_flush
|
||||
return u'\n'.join(sql_flush(self.style, only_django=True)).encode('utf-8')
|
||||
return u'\n'.join(sql_flush(self.style, connections[options.get('database', DEFAULT_DB_ALIAS)], only_django=True)).encode('utf-8')
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import AppCommand
|
||||
from django.core.management.sql import sql_indexes
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
help = "Prints the CREATE INDEX SQL statements for the given model module name(s)."
|
||||
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.core.management.sql import sql_indexes
|
||||
return u'\n'.join(sql_indexes(app, self.style)).encode('utf-8')
|
||||
return u'\n'.join(sql_indexes(app, self.style, connections[options.get('database', DEFAULT_DB_ALIAS)])).encode('utf-8')
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import AppCommand
|
||||
from django.core.management.sql import sql_reset
|
||||
from django.db import connections, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
help = "Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s)."
|
||||
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.core.management.sql import sql_reset
|
||||
return u'\n'.join(sql_reset(app, self.style)).encode('utf-8')
|
||||
return u'\n'.join(sql_reset(app, self.style, connections[options.get('database', DEFAULT_DB_ALIAS)])).encode('utf-8')
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
from optparse import make_option
|
||||
|
||||
from django.core.management.base import AppCommand
|
||||
from django.db import connections, models, DEFAULT_DB_ALIAS
|
||||
|
||||
class Command(AppCommand):
|
||||
help = 'Prints the SQL statements for resetting sequences for the given app name(s).'
|
||||
|
||||
option_list = AppCommand.option_list + (
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to print the '
|
||||
'SQL for. Defaults to the "default" database.'),
|
||||
|
||||
)
|
||||
|
||||
output_transaction = True
|
||||
|
||||
def handle_app(self, app, **options):
|
||||
from django.db import connection, models
|
||||
connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
|
||||
return u'\n'.join(connection.ops.sequence_reset_sql(self.style, models.get_models(app))).encode('utf-8')
|
||||
|
||||
@@ -1,29 +1,32 @@
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from django.core.management.color import no_style
|
||||
from django.utils.importlib import import_module
|
||||
from optparse import make_option
|
||||
import sys
|
||||
|
||||
try:
|
||||
set
|
||||
except NameError:
|
||||
from sets import Set as set # Python 2.3 fallback
|
||||
from django.conf import settings
|
||||
from django.core.management.base import NoArgsCommand
|
||||
from django.core.management.color import no_style
|
||||
from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal
|
||||
from django.db import connections, transaction, models, DEFAULT_DB_ALIAS
|
||||
from django.utils.importlib import import_module
|
||||
|
||||
|
||||
class Command(NoArgsCommand):
|
||||
option_list = NoArgsCommand.option_list + (
|
||||
make_option('--noinput', action='store_false', dest='interactive', default=True,
|
||||
help='Tells Django to NOT prompt the user for input of any kind.'),
|
||||
make_option('--database', action='store', dest='database',
|
||||
default=DEFAULT_DB_ALIAS, help='Nominates a database to synchronize. '
|
||||
'Defaults to the "default" database.'),
|
||||
make_option('-e', '--exclude', dest='exclude',action='append', default=[],
|
||||
help='App to exclude (use multiple --exclude to exclude multiple apps).'),
|
||||
)
|
||||
help = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
|
||||
|
||||
def handle_noargs(self, **options):
|
||||
from django.db import connection, transaction, models
|
||||
from django.conf import settings
|
||||
from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal
|
||||
|
||||
verbosity = int(options.get('verbosity', 1))
|
||||
interactive = options.get('interactive')
|
||||
show_traceback = options.get('traceback', False)
|
||||
exclude = options.get('exclude', [])
|
||||
|
||||
self.style = no_style()
|
||||
|
||||
@@ -46,6 +49,8 @@ class Command(NoArgsCommand):
|
||||
if not msg.startswith('No module named') or 'management' not in msg:
|
||||
raise
|
||||
|
||||
db = options.get('database', DEFAULT_DB_ALIAS)
|
||||
connection = connections[db]
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Get a list of already installed *models* so that references work right.
|
||||
@@ -54,8 +59,11 @@ class Command(NoArgsCommand):
|
||||
created_models = set()
|
||||
pending_references = {}
|
||||
|
||||
excluded_apps = set(models.get_app(app_label) for app_label in exclude)
|
||||
included_apps = set(app for app in models.get_apps() if app not in excluded_apps)
|
||||
|
||||
# Create the tables for each model
|
||||
for app in models.get_apps():
|
||||
for app in included_apps:
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
model_list = models.get_models(app, include_auto_created=True)
|
||||
for model in model_list:
|
||||
@@ -82,22 +90,22 @@ class Command(NoArgsCommand):
|
||||
tables.append(connection.introspection.table_name_converter(model._meta.db_table))
|
||||
|
||||
|
||||
transaction.commit_unless_managed()
|
||||
transaction.commit_unless_managed(using=db)
|
||||
|
||||
# Send the post_syncdb signal, so individual apps can do whatever they need
|
||||
# to do at this point.
|
||||
emit_post_sync_signal(created_models, verbosity, interactive)
|
||||
emit_post_sync_signal(created_models, verbosity, interactive, db)
|
||||
|
||||
# The connection may have been closed by a syncdb handler.
|
||||
cursor = connection.cursor()
|
||||
|
||||
# Install custom SQL for the app (but only if this
|
||||
# is a model we've just created)
|
||||
for app in models.get_apps():
|
||||
for app in included_apps:
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
for model in models.get_models(app):
|
||||
if model in created_models:
|
||||
custom_sql = custom_sql_for_model(model, self.style)
|
||||
custom_sql = custom_sql_for_model(model, self.style, connection)
|
||||
if custom_sql:
|
||||
if verbosity >= 1:
|
||||
print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name)
|
||||
@@ -110,14 +118,15 @@ class Command(NoArgsCommand):
|
||||
if show_traceback:
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
transaction.rollback_unless_managed()
|
||||
transaction.rollback_unless_managed(using=db)
|
||||
else:
|
||||
transaction.commit_unless_managed()
|
||||
transaction.commit_unless_managed(using=db)
|
||||
else:
|
||||
if verbosity >= 2:
|
||||
print "No custom SQL for %s.%s model" % (app_name, model._meta.object_name)
|
||||
|
||||
# Install SQL indicies for all newly created models
|
||||
for app in models.get_apps():
|
||||
for app in included_apps:
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
for model in models.get_models(app):
|
||||
if model in created_models:
|
||||
@@ -131,10 +140,9 @@ class Command(NoArgsCommand):
|
||||
except Exception, e:
|
||||
sys.stderr.write("Failed to install index for %s.%s model: %s\n" % \
|
||||
(app_name, model._meta.object_name, e))
|
||||
transaction.rollback_unless_managed()
|
||||
transaction.rollback_unless_managed(using=db)
|
||||
else:
|
||||
transaction.commit_unless_managed()
|
||||
transaction.commit_unless_managed(using=db)
|
||||
|
||||
# Install the 'initial_data' fixture, using format discovery
|
||||
from django.core.management import call_command
|
||||
call_command('loaddata', 'initial_data', verbosity=verbosity)
|
||||
call_command('loaddata', 'initial_data', verbosity=verbosity, exclude=exclude, database=db)
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
from django.core.management.base import CommandError
|
||||
import os
|
||||
import re
|
||||
|
||||
from django.conf import settings
|
||||
from django.contrib.contenttypes import generic
|
||||
from django.core.management.base import CommandError
|
||||
from django.dispatch import dispatcher
|
||||
from django.db import models
|
||||
from django.db.models import get_models
|
||||
from django.db.backends.util import truncate_name
|
||||
|
||||
try:
|
||||
set
|
||||
except NameError:
|
||||
from sets import Set as set # Python 2.3 fallback
|
||||
|
||||
def sql_create(app, style):
|
||||
def sql_create(app, style, connection):
|
||||
"Returns a list of the CREATE TABLE SQL statements for the given app."
|
||||
from django.db import connection, models
|
||||
from django.conf import settings
|
||||
|
||||
if settings.DATABASE_ENGINE == 'dummy':
|
||||
if connection.settings_dict['ENGINE'] == 'django.db.backends.dummy':
|
||||
# This must be the "dummy" database backend, which means the user
|
||||
# hasn't set DATABASE_ENGINE.
|
||||
# hasn't set ENGINE for the databse.
|
||||
raise CommandError("Django doesn't know which syntax to use for your SQL statements,\n" +
|
||||
"because you haven't specified the DATABASE_ENGINE setting.\n" +
|
||||
"Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.")
|
||||
"because you haven't specified the ENGINE setting for the database.\n" +
|
||||
"Edit your settings file and change DATBASES['default']['ENGINE'] to something like\n" +
|
||||
"'django.db.backends.postgresql' or 'django.db.backends.mysql'")
|
||||
|
||||
# Get installed models, so we generate REFERENCES right.
|
||||
# We trim models from the current app so that the sqlreset command does not
|
||||
@@ -54,11 +60,8 @@ def sql_create(app, style):
|
||||
|
||||
return final_output
|
||||
|
||||
def sql_delete(app, style):
|
||||
def sql_delete(app, style, connection):
|
||||
"Returns a list of the DROP TABLE SQL statements for the given app."
|
||||
from django.db import connection, models
|
||||
from django.db.backends.util import truncate_name
|
||||
from django.contrib.contenttypes import generic
|
||||
|
||||
# This should work even if a connection isn't available
|
||||
try:
|
||||
@@ -101,18 +104,17 @@ def sql_delete(app, style):
|
||||
|
||||
return output[::-1] # Reverse it, to deal with table dependencies.
|
||||
|
||||
def sql_reset(app, style):
|
||||
def sql_reset(app, style, connection):
|
||||
"Returns a list of the DROP TABLE SQL, then the CREATE TABLE SQL, for the given module."
|
||||
return sql_delete(app, style) + sql_all(app, style)
|
||||
return sql_delete(app, style, connection) + sql_all(app, style, connection)
|
||||
|
||||
def sql_flush(style, only_django=False):
|
||||
def sql_flush(style, connection, only_django=False):
|
||||
"""
|
||||
Returns a list of the SQL statements used to flush the database.
|
||||
|
||||
If only_django is True, then only table names that have associated Django
|
||||
models and are in INSTALLED_APPS will be included.
|
||||
"""
|
||||
from django.db import connection
|
||||
if only_django:
|
||||
tables = connection.introspection.django_table_names(only_existing=True)
|
||||
else:
|
||||
@@ -120,35 +122,30 @@ def sql_flush(style, only_django=False):
|
||||
statements = connection.ops.sql_flush(style, tables, connection.introspection.sequence_list())
|
||||
return statements
|
||||
|
||||
def sql_custom(app, style):
|
||||
def sql_custom(app, style, connection):
|
||||
"Returns a list of the custom table modifying SQL statements for the given app."
|
||||
from django.db.models import get_models
|
||||
output = []
|
||||
|
||||
app_models = get_models(app)
|
||||
app_dir = os.path.normpath(os.path.join(os.path.dirname(app.__file__), 'sql'))
|
||||
|
||||
for model in app_models:
|
||||
output.extend(custom_sql_for_model(model, style))
|
||||
output.extend(custom_sql_for_model(model, style, connection))
|
||||
|
||||
return output
|
||||
|
||||
def sql_indexes(app, style):
|
||||
def sql_indexes(app, style, connection):
|
||||
"Returns a list of the CREATE INDEX SQL statements for all models in the given app."
|
||||
from django.db import connection, models
|
||||
output = []
|
||||
for model in models.get_models(app):
|
||||
output.extend(connection.creation.sql_indexes_for_model(model, style))
|
||||
return output
|
||||
|
||||
def sql_all(app, style):
|
||||
def sql_all(app, style, connection):
|
||||
"Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
|
||||
return sql_create(app, style) + sql_custom(app, style) + sql_indexes(app, style)
|
||||
|
||||
def custom_sql_for_model(model, style):
|
||||
from django.db import models
|
||||
from django.conf import settings
|
||||
return sql_create(app, style, connection) + sql_custom(app, style, connection) + sql_indexes(app, style, connection)
|
||||
|
||||
def custom_sql_for_model(model, style, connection):
|
||||
opts = model._meta
|
||||
app_dir = os.path.normpath(os.path.join(os.path.dirname(models.get_app(model._meta.app_label).__file__), 'sql'))
|
||||
output = []
|
||||
@@ -166,7 +163,8 @@ def custom_sql_for_model(model, style):
|
||||
statements = re.compile(r";[ \t]*$", re.M)
|
||||
|
||||
# Find custom SQL, if it's available.
|
||||
sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), settings.DATABASE_ENGINE)),
|
||||
backend_name = connection.settings_dict['ENGINE'].split('.')[-1]
|
||||
sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), backend_name)),
|
||||
os.path.join(app_dir, "%s.sql" % opts.object_name.lower())]
|
||||
for sql_file in sql_files:
|
||||
if os.path.exists(sql_file):
|
||||
@@ -181,9 +179,7 @@ def custom_sql_for_model(model, style):
|
||||
return output
|
||||
|
||||
|
||||
def emit_post_sync_signal(created_models, verbosity, interactive):
|
||||
from django.db import models
|
||||
from django.dispatch import dispatcher
|
||||
def emit_post_sync_signal(created_models, verbosity, interactive, db):
|
||||
# Emit the post_sync signal for every application.
|
||||
for app in models.get_apps():
|
||||
app_name = app.__name__.split('.')[-2]
|
||||
@@ -191,4 +187,4 @@ def emit_post_sync_signal(created_models, verbosity, interactive):
|
||||
print "Running post-sync handlers for application", app_name
|
||||
models.signals.post_syncdb.send(sender=app, app=app,
|
||||
created_models=created_models, verbosity=verbosity,
|
||||
interactive=interactive)
|
||||
interactive=interactive, db=db)
|
||||
|
||||
@@ -36,14 +36,14 @@ except ImportError:
|
||||
_serializers = {}
|
||||
|
||||
def register_serializer(format, serializer_module, serializers=None):
|
||||
""""Register a new serializer.
|
||||
|
||||
""""Register a new serializer.
|
||||
|
||||
``serializer_module`` should be the fully qualified module name
|
||||
for the serializer.
|
||||
|
||||
|
||||
If ``serializers`` is provided, the registration will be added
|
||||
to the provided dictionary.
|
||||
|
||||
|
||||
If ``serializers`` is not provided, the registration will be made
|
||||
directly into the global register of serializers. Adding serializers
|
||||
directly is not a thread-safe operation.
|
||||
@@ -53,7 +53,7 @@ def register_serializer(format, serializer_module, serializers=None):
|
||||
_serializers[format] = module
|
||||
else:
|
||||
serializers[format] = module
|
||||
|
||||
|
||||
def unregister_serializer(format):
|
||||
"Unregister a given serializer. This is not a thread-safe operation."
|
||||
del _serializers[format]
|
||||
@@ -87,7 +87,7 @@ def serialize(format, queryset, **options):
|
||||
s.serialize(queryset, **options)
|
||||
return s.getvalue()
|
||||
|
||||
def deserialize(format, stream_or_string):
|
||||
def deserialize(format, stream_or_string, **options):
|
||||
"""
|
||||
Deserialize a stream or a string. Returns an iterator that yields ``(obj,
|
||||
m2m_relation_dict)``, where ``obj`` is a instantiated -- but *unsaved* --
|
||||
@@ -95,7 +95,7 @@ def deserialize(format, stream_or_string):
|
||||
list_of_related_objects}``.
|
||||
"""
|
||||
d = get_deserializer(format)
|
||||
return d(stream_or_string)
|
||||
return d(stream_or_string, **options)
|
||||
|
||||
def _load_serializers():
|
||||
"""
|
||||
|
||||
@@ -153,15 +153,16 @@ class DeserializedObject(object):
|
||||
self.m2m_data = m2m_data
|
||||
|
||||
def __repr__(self):
|
||||
return "<DeserializedObject: %s>" % smart_str(self.object)
|
||||
return "<DeserializedObject: %s.%s(pk=%s)>" % (
|
||||
self.object._meta.app_label, self.object._meta.object_name, self.object.pk)
|
||||
|
||||
def save(self, save_m2m=True):
|
||||
def save(self, save_m2m=True, using=None):
|
||||
# Call save on the Model baseclass directly. This bypasses any
|
||||
# model-defined save. The save is also forced to be raw.
|
||||
# This ensures that the data that is deserialized is literally
|
||||
# what came from the file, not post-processed by pre_save/save
|
||||
# methods.
|
||||
models.Model.save_base(self.object, raw=True)
|
||||
models.Model.save_base(self.object, using=using, raw=True)
|
||||
if self.m2m_data and save_m2m:
|
||||
for accessor_name, object_list in self.m2m_data.items():
|
||||
setattr(self.object, accessor_name, object_list)
|
||||
|
||||
@@ -39,7 +39,7 @@ def Deserializer(stream_or_string, **options):
|
||||
stream = StringIO(stream_or_string)
|
||||
else:
|
||||
stream = stream_or_string
|
||||
for obj in PythonDeserializer(simplejson.load(stream)):
|
||||
for obj in PythonDeserializer(simplejson.load(stream), **options):
|
||||
yield obj
|
||||
|
||||
class DjangoJSONEncoder(simplejson.JSONEncoder):
|
||||
|
||||
@@ -6,7 +6,7 @@ other serializers.
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.serializers import base
|
||||
from django.db import models
|
||||
from django.db import models, DEFAULT_DB_ALIAS
|
||||
from django.utils.encoding import smart_unicode, is_protected_type
|
||||
|
||||
class Serializer(base.Serializer):
|
||||
@@ -77,6 +77,7 @@ def Deserializer(object_list, **options):
|
||||
It's expected that you pass the Python objects themselves (instead of a
|
||||
stream or a string) to the constructor
|
||||
"""
|
||||
db = options.pop('using', DEFAULT_DB_ALIAS)
|
||||
models.get_apps()
|
||||
for d in object_list:
|
||||
# Look up the model and starting build a dict of data for it.
|
||||
@@ -96,7 +97,7 @@ def Deserializer(object_list, **options):
|
||||
if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
|
||||
def m2m_convert(value):
|
||||
if hasattr(value, '__iter__'):
|
||||
return field.rel.to._default_manager.get_by_natural_key(*value).pk
|
||||
return field.rel.to._default_manager.db_manager(db).get_by_natural_key(*value).pk
|
||||
else:
|
||||
return smart_unicode(field.rel.to._meta.pk.to_python(value))
|
||||
else:
|
||||
@@ -108,7 +109,7 @@ def Deserializer(object_list, **options):
|
||||
if field_value is not None:
|
||||
if hasattr(field.rel.to._default_manager, 'get_by_natural_key'):
|
||||
if hasattr(field_value, '__iter__'):
|
||||
obj = field.rel.to._default_manager.get_by_natural_key(*field_value)
|
||||
obj = field.rel.to._default_manager.db_manager(db).get_by_natural_key(*field_value)
|
||||
value = getattr(obj, field.rel.field_name)
|
||||
else:
|
||||
value = field.rel.to._meta.get_field(field.rel.field_name).to_python(field_value)
|
||||
|
||||
@@ -5,13 +5,9 @@ Requires PyYaml (http://pyyaml.org/), but that's checked for in __init__.
|
||||
"""
|
||||
|
||||
from StringIO import StringIO
|
||||
import decimal
|
||||
import yaml
|
||||
|
||||
try:
|
||||
import decimal
|
||||
except ImportError:
|
||||
from django.utils import _decimal as decimal # Python 2.3 fallback
|
||||
|
||||
from django.db import models
|
||||
from django.core.serializers.python import Serializer as PythonSerializer
|
||||
from django.core.serializers.python import Deserializer as PythonDeserializer
|
||||
@@ -58,6 +54,6 @@ def Deserializer(stream_or_string, **options):
|
||||
stream = StringIO(stream_or_string)
|
||||
else:
|
||||
stream = stream_or_string
|
||||
for obj in PythonDeserializer(yaml.load(stream)):
|
||||
for obj in PythonDeserializer(yaml.load(stream), **options):
|
||||
yield obj
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ XML serializer.
|
||||
|
||||
from django.conf import settings
|
||||
from django.core.serializers import base
|
||||
from django.db import models
|
||||
from django.db import models, DEFAULT_DB_ALIAS
|
||||
from django.utils.xmlutils import SimplerXMLGenerator
|
||||
from django.utils.encoding import smart_unicode
|
||||
from xml.dom import pulldom
|
||||
@@ -149,6 +149,7 @@ class Deserializer(base.Deserializer):
|
||||
def __init__(self, stream_or_string, **options):
|
||||
super(Deserializer, self).__init__(stream_or_string, **options)
|
||||
self.event_stream = pulldom.parse(self.stream)
|
||||
self.db = options.pop('using', DEFAULT_DB_ALIAS)
|
||||
|
||||
def next(self):
|
||||
for event, node in self.event_stream:
|
||||
@@ -218,7 +219,7 @@ class Deserializer(base.Deserializer):
|
||||
if keys:
|
||||
# If there are 'natural' subelements, it must be a natural key
|
||||
field_value = [getInnerText(k).strip() for k in keys]
|
||||
obj = field.rel.to._default_manager.get_by_natural_key(*field_value)
|
||||
obj = field.rel.to._default_manager.db_manager(self.db).get_by_natural_key(*field_value)
|
||||
obj_pk = getattr(obj, field.rel.field_name)
|
||||
else:
|
||||
# Otherwise, treat like a normal PK
|
||||
@@ -239,7 +240,7 @@ class Deserializer(base.Deserializer):
|
||||
if keys:
|
||||
# If there are 'natural' subelements, it must be a natural key
|
||||
field_value = [getInnerText(k).strip() for k in keys]
|
||||
obj_pk = field.rel.to._default_manager.get_by_natural_key(*field_value).pk
|
||||
obj_pk = field.rel.to._default_manager.db_manager(self.db).get_by_natural_key(*field_value).pk
|
||||
else:
|
||||
# Otherwise, treat like a normal PK value.
|
||||
obj_pk = field.rel.to._meta.pk.to_python(n.getAttribute('pk'))
|
||||
|
||||
Reference in New Issue
Block a user