Commits

Konstantine Rybnikov  committed feeba2f

Add skip of non-managed models.

  • Participants
  • Parent commits 9338757

Comments (0)

Files changed (3)

File south/creator/changes.py

     def get_changes(self):
         # Get the frozen models for this app
         model_defs = freeze_apps([self.migrations.app_label()])
-        
+
         for model in models.get_models(models.get_app(self.migrations.app_label())):
-            
             # Don't do anything for unmanaged, abstract or proxy models
-            if model._meta.abstract or getattr(model._meta, "proxy", False) or not getattr(model._meta, "managed", True):
+            if (model._meta.abstract or getattr(model._meta, "proxy", False)
+                or not getattr(model._meta, "managed", True)
+                or model_key(model) not in model_defs):
+
                 continue
-            
-            real_fields, meta, m2m_fields = self.split_model_def(model, model_defs[model_key(model)])
-            
+
+            real_fields, meta, m2m_fields = self.split_model_def(
+                model, model_defs[model_key(model)])
+
             # Firstly, add the main table and fields
             yield ("AddModel", {
                 "model": model,
                 "model_def": real_fields,
             })
-            
+
             # Then, add any uniqueness that's around
             if meta:
                 unique_together = eval(meta.get("unique_together", "[]"))

File south/creator/freezer.py

 from django.db import models
 from django.db.models.base import ModelBase, Model
 from django.contrib.contenttypes.generic import GenericRelation
+try:
+    from django.db import router
+    router_support = True
+except ImportError:
+    router_support = False
 
 from south.orm import FakeORM
 from south.utils import get_attribute, auto_through
 from south import modelsinspector
+from south.db import db_engines
+
 
 def freeze_apps(apps):
     """
     for app in apps:
         for model in models.get_models(models.get_app(app)):
             # Only add if it's not abstract or proxy
-            if not model._meta.abstract and not getattr(model._meta, "proxy", False):
+            if is_managed_model(model):
                 frozen_models.add(model)
     # Now, add all the dependencies
     for model in list(frozen_models):
     for model in frozen_models:
         model_defs[model_key(model)] = prep_for_freeze(model)
         model_classes[model_key(model)] = model
+
     # Check for any custom fields that failed to freeze.
+    missing_fields = has_missing_fields(model_defs, model_classes)
+    if missing_fields:
+        print ""
+        print " ! South cannot introspect some fields; this is probably because they are custom"
+        print " ! fields. If they worked in 0.6 or below, this is because we have removed the"
+        print " ! models parser (it often broke things)."
+        print " ! To fix this, read http://south.aeracode.org/wiki/MyFieldsDontWork"
+        sys.exit(1)
+
+    return model_defs
+
+
+def is_managed_model(model):
+    if model._meta.abstract:
+        return False
+    if getattr(model._meta, "proxy", False):
+        return False
+    if router_support:
+        db_name = router.db_for_write(model)
+        if db_name in db_engines.keys():
+            return True
+        else:
+            return False
+    return True
+
+
+def has_missing_fields(model_defs, model_classes):
     missing_fields = False
     for key, fields in model_defs.items():
         for field_name, value in fields.items():
                 model_class = model_classes[key]
                 field_class = model_class._meta.get_field_by_name(field_name)[0]
                 print " ! Cannot freeze field '%s.%s'" % (key, field_name)
-                print " ! (this field has class %s.%s)" % (field_class.__class__.__module__, field_class.__class__.__name__)
-    if missing_fields:
-        print ""
-        print " ! South cannot introspect some fields; this is probably because they are custom"
-        print " ! fields. If they worked in 0.6 or below, this is because we have removed the"
-        print " ! models parser (it often broke things)."
-        print " ! To fix this, read http://south.aeracode.org/wiki/MyFieldsDontWork"
-        sys.exit(1)
-    
-    return model_defs
-    
+                print " ! (this field has class %s.%s)" % (
+                    field_class.__class__.__module__,
+                    field_class.__class__.__name__)
+    return missing_fields
+
+
 def freeze_apps_to_string(apps):
     return pprint_frozen_models(freeze_apps(apps))
-    
-### 
+
 
 def model_key(model):
     "For a given model, return 'appname.modelname'."
     return "%s.%s" % (model._meta.app_label, model._meta.object_name.lower())
 
+
 def prep_for_freeze(model):
     """
     Takes a model and returns the ready-to-serialise dict (all you need

File south/tests/freezer.py

+# from mock import Mock, patch
 import unittest
 
 from south.creator.freezer import model_dependencies
+# from south.creator.freezer import freeze_apps
+# from south.creator.freezer import is_managed_model
 from south.tests.fakeapp import models
 
+
 class TestFreezer(unittest.TestCase):
     def test_dependencies(self):
         self.assertEqual(set(model_dependencies(models.SubModel)),
 
         self.assertEqual(set(model_dependencies(models.Recursive)),
                          set([models.Recursive]))
+
+    # @patch('south.creator.freezer.has_missing_fields')
+    # @patch('south.creator.freezer.prep_for_freeze')
+    # @patch('south.creator.freezer.model_dependencies')
+    # @patch('south.creator.freezer.model_key')
+    # @patch('south.creator.freezer.models.get_models')
+    # @patch('south.creator.freezer.models.get_app')
+    # @patch('south.creator.freezer.is_managed_model')
+    # def test_should_skip_nonmanaged_models(
+    #     self, is_managed_model_mock,
+    #     get_app_mock, get_models_mock, model_key_mock,
+    #     model_dependencies_mock, prep_for_freeze_mock,
+    #     has_missing_fields_mock):
+
+    #     app = Mock()
+    #     get_app_mock.return_value = app
+    #     apps = ["app"]
+    #     m1 = Mock()
+    #     m1_key = Mock()
+    #     m1_prep = Mock()
+    #     m2 = Mock()
+    #     m2_key = Mock()
+    #     m2_prep = Mock()
+    #     m3 = Mock()
+    #     m3_key = Mock()
+    #     m3_prep = Mock()
+    #     get_models_mock.return_value = [m1, m2, m3]
+    #     model_dependencies_mock.return_value = []
+    #     has_missing_fields_mock.return_value = False
+
+    #     def is_m_sf(model):
+    #         if model == m2:
+    #             return False
+    #         return True
+    #     is_managed_model_mock.side_effect = is_m_sf
+
+    #     def mk_se(x):
+    #         rv = {m1: m1_key,
+    #               m2: m2_key,
+    #               m3: m3_key}
+    #         return rv.get(x)
+    #     model_key_mock.side_effect = mk_se
+
+    #     def prep_se(x):
+    #         rv = {m1: m1_prep,
+    #               m2: m2_prep,
+    #               m3: m3_prep}
+    #         return rv[x]
+    #     prep_for_freeze_mock.side_effect = prep_se
+
+    #     # do
+    #     model_defs = freeze_apps(apps)
+
+    #     self.assertEqual(
+    #         model_defs,
+    #         {m1_key: m1_prep,
+    #          m3_key: m3_prep})
+
+    # @patch('south.creator.freezer.db_engines')
+    # @patch('south.creator.freezer.router')
+    # def test_should_check_if_model_is_managed(
+    #     self, router_mock, db_engines_mock):
+
+    #     model = Mock()
+    #     model._meta.abstract = False
+    #     model._meta.proxy = False
+    #     db_engines_mock.keys.return_value = ['db_first', 'db_second']
+
+    #     router_mock.db_for_write.return_value = 'db_first'
+    #     # do
+    #     result = is_managed_model(model)
+    #     self.assertEquals(result, True)
+
+    #     router_mock.db_for_write.return_value = 'db_third'
+    #     # do
+    #     result = is_managed_model(model)
+    #     self.assertEquals(result, False)