Loading django/core/management/commands/inspectdb.py +21 −13 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ from collections import OrderedDict from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS, connections from django.utils.encoding import force_text class Command(BaseCommand): Loading Loading @@ -57,10 +58,7 @@ class Command(BaseCommand): if table_name_filter is not None and callable(table_name_filter): if not table_name_filter(table_name): continue yield '' yield '' yield 'class %s(models.Model):' % table2model(table_name) known_models.append(table2model(table_name)) try: try: relations = connection.introspection.get_relations(cursor, table_name) except NotImplementedError: Loading @@ -73,9 +71,19 @@ class Command(BaseCommand): constraints = connection.introspection.get_constraints(cursor, table_name) except NotImplementedError: constraints = {} table_description = connection.introspection.get_table_description(cursor, table_name) except Exception as e: yield "# Unable to inspect table '%s'" % table_name yield "# The error was: %s" % force_text(e) continue yield '' yield '' yield 'class %s(models.Model):' % table2model(table_name) known_models.append(table2model(table_name)) used_column_names = [] # Holds column names used in the table so far column_to_field_name = {} # Maps column names to names of model fields for row in connection.introspection.get_table_description(cursor, table_name): for row in table_description: comment_notes = [] # Holds Field notes, to be displayed in a Python comment. extra_params = OrderedDict() # Holds Field parameters such as 'db_column'. column_name = row[0] Loading tests/inspectdb/tests.py +16 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,8 @@ from unittest import skipUnless from django.core.management import call_command from django.db import connection from django.test import TestCase, skipUnlessDBFeature from django.test import TestCase, mock, skipUnlessDBFeature from django.utils.encoding import force_text from django.utils.six import PY3, StringIO from .models import ColumnTypes Loading Loading @@ -268,3 +269,17 @@ class InspectDBTestCase(TestCase): self.assertIn("big_int_field = models.BigIntegerField()", output) finally: connection.introspection.data_types_reverse = orig_data_types_reverse def test_introspection_errors(self): """ Introspection errors should not crash the command, and the error should be visible in the output. """ out = StringIO() with mock.patch('django.db.backends.base.introspection.BaseDatabaseIntrospection.table_names', return_value=['nonexistent']): call_command('inspectdb', stdout=out) output = force_text(out.getvalue()) self.assertIn("# Unable to inspect table 'nonexistent'", output) # The error message depends on the backend self.assertIn("# The error was:", output) Loading
django/core/management/commands/inspectdb.py +21 −13 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ from collections import OrderedDict from django.core.management.base import BaseCommand, CommandError from django.db import DEFAULT_DB_ALIAS, connections from django.utils.encoding import force_text class Command(BaseCommand): Loading Loading @@ -57,10 +58,7 @@ class Command(BaseCommand): if table_name_filter is not None and callable(table_name_filter): if not table_name_filter(table_name): continue yield '' yield '' yield 'class %s(models.Model):' % table2model(table_name) known_models.append(table2model(table_name)) try: try: relations = connection.introspection.get_relations(cursor, table_name) except NotImplementedError: Loading @@ -73,9 +71,19 @@ class Command(BaseCommand): constraints = connection.introspection.get_constraints(cursor, table_name) except NotImplementedError: constraints = {} table_description = connection.introspection.get_table_description(cursor, table_name) except Exception as e: yield "# Unable to inspect table '%s'" % table_name yield "# The error was: %s" % force_text(e) continue yield '' yield '' yield 'class %s(models.Model):' % table2model(table_name) known_models.append(table2model(table_name)) used_column_names = [] # Holds column names used in the table so far column_to_field_name = {} # Maps column names to names of model fields for row in connection.introspection.get_table_description(cursor, table_name): for row in table_description: comment_notes = [] # Holds Field notes, to be displayed in a Python comment. extra_params = OrderedDict() # Holds Field parameters such as 'db_column'. column_name = row[0] Loading
tests/inspectdb/tests.py +16 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,8 @@ from unittest import skipUnless from django.core.management import call_command from django.db import connection from django.test import TestCase, skipUnlessDBFeature from django.test import TestCase, mock, skipUnlessDBFeature from django.utils.encoding import force_text from django.utils.six import PY3, StringIO from .models import ColumnTypes Loading Loading @@ -268,3 +269,17 @@ class InspectDBTestCase(TestCase): self.assertIn("big_int_field = models.BigIntegerField()", output) finally: connection.introspection.data_types_reverse = orig_data_types_reverse def test_introspection_errors(self): """ Introspection errors should not crash the command, and the error should be visible in the output. """ out = StringIO() with mock.patch('django.db.backends.base.introspection.BaseDatabaseIntrospection.table_names', return_value=['nonexistent']): call_command('inspectdb', stdout=out) output = force_text(out.getvalue()) self.assertIn("# Unable to inspect table 'nonexistent'", output) # The error message depends on the backend self.assertIn("# The error was:", output)