Commit 08dc90bc authored by Ramiro Morales's avatar Ramiro Morales
Browse files

Fixed #14305 -- Switched inspectdb to create unmanaged models.

Thanks Ian Kelly for the report and initial patch.
parent c9c40bc6
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ class Command(NoArgsCommand):
        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 "#   * 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,
                ""]
+29 −0
Original line number Diff line number Diff line
@@ -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 <django.db.models.Options.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
==============================

+15 −0
Original line number Diff line number Diff line
@@ -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 <django.db.models.Options.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 <fixture fixture ...>
------------------------------

+10 −0
Original line number Diff line number Diff line
@@ -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.')