From 08dc90bccf7c4ffa8b04064d74b54c1150af5ff9 Mon Sep 17 00:00:00 2001 From: Ramiro Morales Date: Sat, 2 Feb 2013 21:08:45 -0300 Subject: [PATCH] Fixed #14305 -- Switched inspectdb to create unmanaged models. Thanks Ian Kelly for the report and initial patch. --- django/core/management/commands/inspectdb.py | 6 ++-- docs/howto/legacy-databases.txt | 29 ++++++++++++++++++++ docs/ref/django-admin.txt | 15 ++++++++++ tests/regressiontests/inspectdb/tests.py | 10 +++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py index f9cecc2f5f..42cc9c5dfe 100644 --- a/django/core/management/commands/inspectdb.py +++ b/django/core/management/commands/inspectdb.py @@ -40,8 +40,9 @@ class Command(NoArgsCommand): cursor = connection.cursor() yield "# This is an auto-generated Django model module." yield "# You'll have to do the following manually to clean this up:" - yield "# * Rearrange models' order" - yield "# * Make sure each model has one field with primary_key=True" + yield "# * Rearrange models' order" + yield "# * Make sure each model has one field with primary_key=True" + yield "# * Remove `managed = False` lines for those models you wish to give write DB access" yield "# Feel free to rename the models, but don't rename db_table values or field names." yield "#" yield "# Also note: You'll have to insert the output of 'django-admin.py sqlcustom [appname]'" @@ -224,5 +225,6 @@ class Command(NoArgsCommand): to the given database table name. """ return [" class Meta:", + " managed = False", " db_table = '%s'" % table_name, ""] diff --git a/docs/howto/legacy-databases.txt b/docs/howto/legacy-databases.txt index 3e75ef1e5f..67bce7e976 100644 --- a/docs/howto/legacy-databases.txt +++ b/docs/howto/legacy-databases.txt @@ -49,6 +49,35 @@ Once you've cleaned up your models, name the file ``models.py`` and put it in the Python package that holds your app. Then add the app to your :setting:`INSTALLED_APPS` setting. +If your plan is that your Django application(s) modify data (i.e. edit, remove +records and create new ones) in the existing database tables corresponding to +any of the introspected models then one of the manual review and edit steps +you need to perform on the resulting ``models.py`` file is to change the +Python declaration of each one of these models to specify it is a +:attr:`managed ` one. For example, consider +this generated model definition: + +.. parsed-literal:: + + class Person(models.Model): + id = models.IntegerField(primary_key=True) + first_name = models.ChaField(max_length=70) + class Meta: + **managed = False** + db_table = 'CENSUS_PERSONS' + +If you wanted to modify existing data on your ``CENSUS_PERSONS`` SQL table +with Django you'd need to change the ``managed`` option highlighted above to +``True`` (or simply remove it to let it because ``True`` is its default value). + +This servers as an explicit opt-in to give your nascent Django project write +access to your precious data on a model by model basis. + +.. versionchanged:: 1.6 + +The behavior by which introspected models are created as unmanaged ones is new +in Django 1.6. + Install the core Django tables ============================== diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt index 8f6664edb7..4074495b9a 100644 --- a/docs/ref/django-admin.txt +++ b/docs/ref/django-admin.txt @@ -288,9 +288,24 @@ needed. ``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection only works in PostgreSQL and with certain types of MySQL tables. +If your plan is that your Django application(s) modify data (i.e. edit, remove +records and create new ones) in the existing database tables corresponding to +any of the introspected models then one of the manual review and edit steps +you need to perform on the resulting ``models.py`` file is to change the +Python declaration of each one of these models to specify it is a +:attr:`managed ` one. + +This servers as an explicit opt-in to give your nascent Django project write +access to your precious data on a model by model basis. + The :djadminopt:`--database` option may be used to specify the database to introspect. +.. versionchanged:: 1.6 + +The behavior by which introspected models are created as unmanaged ones is new +in Django 1.6. + loaddata ------------------------------ diff --git a/tests/regressiontests/inspectdb/tests.py b/tests/regressiontests/inspectdb/tests.py index 33fd567546..d77e21bf92 100644 --- a/tests/regressiontests/inspectdb/tests.py +++ b/tests/regressiontests/inspectdb/tests.py @@ -140,3 +140,13 @@ class InspectDBTestCase(TestCase): self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output) self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output) self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output) + + def test_managed_models(self): + """Test that by default the command generates models with `Meta.managed = False` (#14305)""" + out = StringIO() + call_command('inspectdb', + table_name_filter=lambda tn:tn.startswith('inspectdb_columntypes'), + stdout=out) + output = out.getvalue() + self.longMessage = False + self.assertIn(" managed = False", output, msg='inspectdb should generate unmanaged models.')