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

Thanks Ian Kelly for the report and initial patch.
This commit is contained in:
Ramiro Morales 2013-02-02 21:08:45 -03:00
parent c9c40bc6bc
commit 08dc90bccf
4 changed files with 58 additions and 2 deletions

View File

@ -40,8 +40,9 @@ class Command(NoArgsCommand):
cursor = connection.cursor() cursor = connection.cursor()
yield "# This is an auto-generated Django model module." yield "# This is an auto-generated Django model module."
yield "# You'll have to do the following manually to clean this up:" yield "# You'll have to do the following manually to clean this up:"
yield "# * Rearrange models' order" yield "# * Rearrange models' order"
yield "# * Make sure each model has one field with primary_key=True" 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 "# Feel free to rename the models, but don't rename db_table values or field names."
yield "#" yield "#"
yield "# Also note: You'll have to insert the output of 'django-admin.py sqlcustom [appname]'" 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. to the given database table name.
""" """
return [" class Meta:", return [" class Meta:",
" managed = False",
" db_table = '%s'" % table_name, " db_table = '%s'" % table_name,
""] ""]

View File

@ -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 the Python package that holds your app. Then add the app to your
:setting:`INSTALLED_APPS` setting. :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 Install the core Django tables
============================== ==============================

View File

@ -288,9 +288,24 @@ needed.
``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection ``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection
only works in PostgreSQL and with certain types of MySQL tables. 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 The :djadminopt:`--database` option may be used to specify the
database to introspect. 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 ...> loaddata <fixture fixture ...>
------------------------------ ------------------------------

View File

@ -140,3 +140,13 @@ class InspectDBTestCase(TestCase):
self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output) 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("field_field_1 = models.IntegerField(db_column='__field')", output)
self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", 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.')