Permalink
Browse files

Fixed #13636 -- Migrated fixtures tests to use unittests, eliminating…

… another set of expensive flush calls. Thanks to Eric Holscher for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13319 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
1 parent 3e1e04d commit 5da6aeba17060fb986ae209a3f463383454b2970 @freakboy3742 freakboy3742 committed Jun 5, 2010
@@ -213,6 +213,8 @@ def execute(self, *args, **options):
sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
sys.exit(1)
try:
+ self.stdout = options.get('stdout', sys.stdout)
+ self.stderr = options.get('stderr', sys.stderr)
if self.requires_model_validation:
self.validate()
output = self.handle(*args, **options)
@@ -223,12 +225,12 @@ def execute(self, *args, **options):
from django.db import connections, DEFAULT_DB_ALIAS
connection = connections[options.get('database', DEFAULT_DB_ALIAS)]
if connection.ops.start_transaction_sql():
- print self.style.SQL_KEYWORD(connection.ops.start_transaction_sql())
- print output
+ self.stdout.write(self.style.SQL_KEYWORD(connection.ops.start_transaction_sql()))
+ self.stdout.write(output)
if self.output_transaction:
- print self.style.SQL_KEYWORD(connection.ops.end_transaction_sql())
+ self.stdout.write(self.style.SQL_KEYWORD("COMMIT;") + '\n')
except CommandError, e:
- sys.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
+ self.stderr.write(smart_str(self.style.ERROR('Error: %s\n' % e)))
sys.exit(1)
def validate(self, app=None, display_num_errors=False):
@@ -250,7 +252,7 @@ def validate(self, app=None, display_num_errors=False):
error_text = s.read()
raise CommandError("One or more models did not validate:\n%s" % error_text)
if display_num_errors:
- print "%s error%s found" % (num_errors, num_errors != 1 and 's' or '')
+ self.stdout.write("%s error%s found\n" % (num_errors, num_errors != 1 and 's' or ''))
def handle(self, *args, **options):
"""
@@ -112,10 +112,10 @@ def read(self):
if formats:
if verbosity > 1:
- print "Loading '%s' fixtures..." % fixture_name
+ self.stdout.write("Loading '%s' fixtures...\n" % fixture_name)
else:
sys.stderr.write(
- self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format." %
+ self.style.ERROR("Problem installing fixture '%s': %s is not a known serialization format.\n" %
(fixture_name, format)))
transaction.rollback(using=using)
transaction.leave_transaction_management(using=using)
@@ -128,7 +128,7 @@ def read(self):
for fixture_dir in fixture_dirs:
if verbosity > 1:
- print "Checking %s for fixtures..." % humanize(fixture_dir)
+ self.stdout.write("Checking %s for fixtures...\n" % humanize(fixture_dir))
label_found = False
for combo in product([using, None], formats, compression_formats):
@@ -141,25 +141,25 @@ def read(self):
)
if verbosity > 1:
- print "Trying %s for %s fixture '%s'..." % \
- (humanize(fixture_dir), file_name, fixture_name)
+ self.stdout.write("Trying %s for %s fixture '%s'...\n" % \
+ (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)))
+ self.stderr.write(self.style.ERROR("Multiple fixtures named '%s' in %s. Aborting.\n" %
+ (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))
+ self.stdout.write("Installing %s fixture '%s' from %s.\n" % \
+ (format, fixture_name, humanize(fixture_dir)))
try:
objects = serializers.deserialize(format, fixture, using=using)
for obj in objects:
@@ -190,24 +190,24 @@ def read(self):
# 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.)" %
+ self.style.ERROR("No fixture data found for '%s'. (File format may be invalid.)\n" %
(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))
+ self.stdout.write("No %s fixture '%s' in %s.\n" % \
+ (format, fixture_name, humanize(fixture_dir)))
# If we found even one object in a fixture, we need to reset the
# database sequences.
if object_count > 0:
sequence_sql = connection.ops.sequence_reset_sql(self.style, models)
if sequence_sql:
if verbosity > 1:
- print "Resetting sequences"
+ self.stdout.write("Resetting sequences\n")
for line in sequence_sql:
cursor.execute(line)
@@ -217,10 +217,10 @@ def read(self):
if object_count == 0:
if verbosity > 0:
- print "No fixtures found."
+ self.stdout.write("No fixtures found.\n")
else:
if verbosity > 0:
- print "Installed %d object(s) from %d fixture(s)" % (object_count, fixture_count)
+ self.stdout.write("Installed %d object(s) from %d fixture(s)\n" % (object_count, fixture_count))
# Close the DB connection. This is required as a workaround for an
# edge case in MySQL: if the same connection is used to
@@ -8,7 +8,7 @@ Writing custom django-admin commands
Applications can register their own actions with ``manage.py``. For example,
you might want to add a ``manage.py`` action for a Django app that you're
-distributing. In this document, we will be building a custom ``closepoll``
+distributing. In this document, we will be building a custom ``closepoll``
command for the ``polls`` application from the
:ref:`tutorial<intro-tutorial01>`.
@@ -62,9 +62,16 @@ look like this:
poll.opened = False
poll.save()
- print 'Successfully closed poll "%s"' % poll_id
+ self.stdout.write('Successfully closed poll "%s"\n' % poll_id)
-The new custom command can be called using ``python manage.py closepoll
+.. note::
+ When you are using management commands and wish to provide console
+ output, you should write to ``self.stdout`` and ``self.stderr``,
+ instead of printing to ``stdout`` and ``stderr`` directly. By
+ using these proxies, it becomes much easier to test your custom
+ command.
+
+The new custom command can be called using ``python manage.py closepoll
<poll_id>``.
The ``handle()`` method takes zero or more ``poll_ids`` and sets ``poll.opened``
@@ -91,8 +98,8 @@ must be added to :attr:`~BaseCommand.option_list` like this:
)
# ...
-In addition to being able to add custom command line options, all
-:ref:`management commands<ref-django-admin>` can accept some
+In addition to being able to add custom command line options, all
+:ref:`management commands<ref-django-admin>` can accept some
default options such as :djadminopt:`--verbosity` and :djadminopt:`--traceback`.
Command objects
@@ -113,7 +120,7 @@ Subclassing the :class:`BaseCommand` class requires that you implement the
Attributes
----------
-All attributes can be set in your derived class and can be used in
+All attributes can be set in your derived class and can be used in
:class:`BaseCommand`'s :ref:`subclasses<ref-basecommand-subclasses>`.
.. attribute:: BaseCommand.args
@@ -133,7 +140,7 @@ All attributes can be set in your derived class and can be used in
.. attribute:: BaseCommand.help
A short description of the command, which will be printed in the
- help message when the user runs the command
+ help message when the user runs the command
``python manage.py help <command>``.
.. attribute:: BaseCommand.option_list
@@ -230,7 +237,7 @@ Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
A command which takes no arguments on the command line.
Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
-:meth:`~NoArgsCommand.handle_noargs`; :meth:`~BaseCommand.handle` itself is
+:meth:`~NoArgsCommand.handle_noargs`; :meth:`~BaseCommand.handle` itself is
overridden to ensure no arguments are passed to the command.
.. method:: NoArgsCommand.handle_noargs(**options)
Oops, something went wrong.

0 comments on commit 5da6aeb

Please sign in to comment.