Ticket #12672: t12672-r12278.2.diff
File t12672-r12278.2.diff, 14.4 KB (added by , 15 years ago) |
---|
-
django/core/management/commands/loaddata.py
diff -r d205a9ab4b3b django/core/management/commands/loaddata.py
a b 8 8 from django.core import serializers 9 9 from django.core.management.base import BaseCommand 10 10 from django.core.management.color import no_style 11 from django.db import connections, transaction, DEFAULT_DB_ALIAS11 from django.db import connections, router, transaction, DEFAULT_DB_ALIAS 12 12 from django.db.models import get_apps 13 13 from django.utils.itercompat import product 14 14 15 15 try: 16 set17 except NameError:18 from sets import Set as set # Python 2.3 fallback19 20 try:21 16 import bz2 22 17 has_bz2 = True 23 18 except ImportError: … … 31 26 make_option('--database', action='store', dest='database', 32 27 default=DEFAULT_DB_ALIAS, help='Nominates a specific database to load ' 33 28 'fixtures into. Defaults to the "default" database.'), 34 make_option('-e', '--exclude', dest='exclude',action='append', default=[],35 help='App to exclude (use multiple --exclude to exclude multiple apps).'),36 29 ) 37 30 38 31 def handle(self, *fixture_labels, **options): 39 32 using = options.get('database', DEFAULT_DB_ALIAS) 40 excluded_apps = options.get('exclude', [])41 33 42 34 connection = connections[using] 43 35 self.style = no_style() … … 171 163 try: 172 164 objects = serializers.deserialize(format, fixture, using=using) 173 165 for obj in objects: 174 if obj.object._meta.app_label not in excluded_apps:166 if router.allow_syncdb(using, obj.object.__class__): 175 167 objects_in_fixture += 1 176 168 models.add(obj.object.__class__) 177 169 obj.save(using=using) -
django/core/management/commands/syncdb.py
diff -r d205a9ab4b3b django/core/management/commands/syncdb.py
a b 5 5 from django.core.management.base import NoArgsCommand 6 6 from django.core.management.color import no_style 7 7 from django.core.management.sql import custom_sql_for_model, emit_post_sync_signal 8 from django.db import connections, transaction, models, DEFAULT_DB_ALIAS8 from django.db import connections, router, transaction, models, DEFAULT_DB_ALIAS 9 9 from django.utils.importlib import import_module 10 10 11 11 … … 16 16 make_option('--database', action='store', dest='database', 17 17 default=DEFAULT_DB_ALIAS, help='Nominates a database to synchronize. ' 18 18 'Defaults to the "default" database.'), 19 make_option('-e', '--exclude', dest='exclude',action='append', default=[],20 help='App to exclude (use multiple --exclude to exclude multiple apps).'),21 19 ) 22 20 help = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created." 23 21 … … 26 24 verbosity = int(options.get('verbosity', 1)) 27 25 interactive = options.get('interactive') 28 26 show_traceback = options.get('traceback', False) 29 exclude = options.get('exclude', [])30 27 31 28 self.style = no_style() 32 29 … … 59 56 created_models = set() 60 57 pending_references = {} 61 58 62 excluded_apps = set(models.get_app(app_label) for app_label in exclude) 63 included_apps = set(app for app in models.get_apps() if app not in excluded_apps) 59 # Build the manifest of apps and models that are to be synchronized 60 manifest = dict( 61 (app.__name__.split('.')[-2], 62 [m for m in models.get_models(app, include_auto_created=True) 63 if router.allow_syncdb(db, m)]) 64 for app in models.get_apps() 65 ) 64 66 65 67 # Create the tables for each model 66 for app in included_apps: 67 app_name = app.__name__.split('.')[-2] 68 model_list = models.get_models(app, include_auto_created=True) 68 for app_name, model_list in manifest.items(): 69 69 for model in model_list: 70 70 # Create the model's database table, if it doesn't already exist. 71 71 if verbosity >= 2: … … 101 101 102 102 # Install custom SQL for the app (but only if this 103 103 # is a model we've just created) 104 for app in included_apps: 105 app_name = app.__name__.split('.')[-2] 106 for model in models.get_models(app): 104 for app_name, model_list in manifest.items(): 105 for model in model_list: 107 106 if model in created_models: 108 107 custom_sql = custom_sql_for_model(model, self.style, connection) 109 108 if custom_sql: … … 126 125 print "No custom SQL for %s.%s model" % (app_name, model._meta.object_name) 127 126 128 127 # Install SQL indicies for all newly created models 129 for app in included_apps: 130 app_name = app.__name__.split('.')[-2] 131 for model in models.get_models(app): 128 for app_name, model_list in manifest.items(): 129 for model in model_list: 132 130 if model in created_models: 133 131 index_sql = connection.creation.sql_indexes_for_model(model, self.style) 134 132 if index_sql: … … 145 143 transaction.commit_unless_managed(using=db) 146 144 147 145 from django.core.management import call_command 148 call_command('loaddata', 'initial_data', verbosity=verbosity, exclude=exclude,database=db)146 call_command('loaddata', 'initial_data', verbosity=verbosity, database=db) -
django/db/utils.py
diff -r d205a9ab4b3b django/db/utils.py
a b 120 120 if allow is not None: 121 121 return allow 122 122 return obj1._state.db == obj2._state.db 123 124 def allow_syncdb(self, db, model): 125 for router in self.routers: 126 allow = router.allow_syncdb(db, model) 127 if allow is not None: 128 return allow 129 return True -
docs/ref/django-admin.txt
diff -r d205a9ab4b3b docs/ref/django-admin.txt
a b 423 423 have specified that you want to load data onto the ``master`` 424 424 database. 425 425 426 Excluding applications from loading427 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~428 429 .. versionadded:: 1.2430 431 The :djadminopt:`--exclude` option may be provided to prevent specific432 applications from being loaded.433 434 For example, if you wanted to exclude models from ``django.contrib.auth``435 from being loaded into your database, you would call::436 437 django-admin.py loaddata mydata.json --exclude auth438 439 This will look for for a JSON fixture called ``mydata`` in all the440 usual locations - including the ``fixtures`` directory of the441 ``django.contrib.auth`` application. However, any fixture object that442 identifies itself as belonging to the ``auth`` application (e.g.,443 instance of ``auth.User``) would be ignored by loaddata.444 445 426 makemessages 446 427 ------------ 447 428 -
docs/topics/db/multi-db.txt
diff -r d205a9ab4b3b docs/topics/db/multi-db.txt
a b 66 66 $ ./manage.py syncdb --database=users 67 67 68 68 If you don't want every application to be synchronized onto a 69 particular database. you can specify the :djadminopt:`--exclude` 70 argument to :djadmin:`syncdb`. The :djadminopt:`--exclude` option lets 71 you prevent a specific application or applications from being 72 synchronized. For example, if you don't want the ``sales`` application 73 to be in the ``users`` database, you could run:: 74 75 $ ./manage.py syncdb --database=users --exclude=sales 69 particular database, you can define a :ref:`database 70 router<topics-db-multi-db-routing>` that implements a policy 71 constraining the availability of particular models. 76 72 77 73 Alternatively, if you want fine-grained control of synchronization, 78 74 you can pipe all or part of the output of :djadmin:`sqlall` for a … … 103 99 Database routers 104 100 ---------------- 105 101 106 A database Router is a class that provides threemethods:102 A database Router is a class that provides four methods: 107 103 108 104 .. method:: db_for_read(model, **hints) 109 105 … … 137 133 used by foreign key and many to many operations to determine if a 138 134 relation should be allowed between two objects. 139 135 136 .. method:: allow_syncdb(db, model) 137 138 Determine if the ``model`` should be synchronized onto the 139 database with alias ``db``. Return True if the model should be 140 synchronized, False if it should not be synchronized, or None if 141 the router has no opinion. This method can be used to determine 142 the availability of a model on a given database. 143 140 144 .. _topics-db-multi-db-hints: 141 145 142 146 Hints … … 221 225 return True 222 226 return None 223 227 228 def allow_syncdb(self, db, model): 229 "Make sure the auth app only appears on the 'credentials' db" 230 if db == 'credentials': 231 return model._meta.app_label == 'auth' 232 elif model._meta.app_label == 'auth': 233 return False 234 return None 224 235 225 236 class MasterSlaveRouter(object): 226 237 """A router that sets up a simple master/slave configuration""" … … 240 251 return True 241 252 return None 242 253 254 def allow_syncdb(self, db, model): 255 "Explicitly put all models on all databases." 256 return True 257 243 258 Then, in your settings file, add the following (substituting ``path.to.`` with 244 259 the actual python path to the module where you define the routers):: 245 260 246 261 DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.MasterSlaveRouter'] 247 262 263 The order in which routers are processed is significant. Routers will 264 be queried in the order the are listed in the 265 :setting:`DATABASE_ROUTERS` setting . In this example, the 266 ``AuthRouter`` is processed before the ``MasterSlaveRouter``, and as a 267 result, decisions concerning the models in ``auth`` are processed 268 before any other decision is made. If the :setting:`DATABASE_ROUTERS` 269 setting listed the two routers in the other order, 270 ``MasterSlaveRouter.allow_syncdb()`` would be processed first. The 271 catch-all nature of the MasterSlaveRouter implementation would mean 272 that all models would be available on all databases. 273 248 274 With this setup installed, lets run some Django code:: 249 275 250 276 >>> # This retrieval will be performed on the 'credentials' database … … 270 296 >>> # ... but if we re-retrieve the object, it will come back on a slave 271 297 >>> mh = Book.objects.get(title='Mostly Harmless') 272 298 299 273 300 Manually selecting a database 274 301 ============================= 275 302 -
tests/modeltests/fixtures/models.py
diff -r d205a9ab4b3b tests/modeltests/fixtures/models.py
a b 289 289 290 290 >>> management.call_command('flush', verbosity=0, interactive=False) 291 291 292 # Try to load fixture 1, but this time, exclude the 'fixtures' app.293 >>> management.call_command('loaddata', 'fixture1', verbosity=0, exclude='fixtures')294 >>> Article.objects.all()295 [<Article: Python program becomes self aware>]296 297 >>> Category.objects.all()298 []299 300 292 # Load back in fixture 1, we need the articles from it 301 293 >>> management.call_command('loaddata', 'fixture1', verbosity=0) 302 294 -
tests/regressiontests/multiple_database/tests.py
diff -r d205a9ab4b3b tests/regressiontests/multiple_database/tests.py
a b 655 655 def allow_relation(self, obj1, obj2, **hints): 656 656 return obj1._state.db in ('default', 'other') and obj2._state.db in ('default', 'other') 657 657 658 def allow_syncdb(self, db, model): 659 return True 660 661 class AuthRouter(object): 662 # Another test router. This one doesn't do anything interesting 663 # other than validate syncdb behavior 664 def db_for_read(self, model, **hints): 665 return None 666 def db_for_write(self, model, **hints): 667 return None 668 def allow_relation(self, obj1, obj2, **hints): 669 return None 670 def allow_syncdb(self, db, model): 671 if db == 'other': 672 return model._meta.app_label == 'auth' 673 elif model._meta.app_label == 'auth': 674 return False 675 return None 676 658 677 class RouterTestCase(TestCase): 659 678 multi_db = True 660 679 … … 677 696 self.assertEquals(Book.objects.db_manager('default').db, 'default') 678 697 self.assertEquals(Book.objects.db_manager('default').all().db, 'default') 679 698 699 def test_syncdb_selection(self): 700 "Synchronization behaviour is predicatable" 701 702 self.assertTrue(router.allow_syncdb('default', User)) 703 self.assertTrue(router.allow_syncdb('default', Book)) 704 705 self.assertTrue(router.allow_syncdb('other', User)) 706 self.assertTrue(router.allow_syncdb('other', Book)) 707 708 # Add the auth router to the chain. 709 # TestRouter is a universal synchronizer, so it should have no effect. 710 router.routers = [TestRouter(), AuthRouter()] 711 712 self.assertTrue(router.allow_syncdb('default', User)) 713 self.assertTrue(router.allow_syncdb('default', Book)) 714 715 self.assertTrue(router.allow_syncdb('other', User)) 716 self.assertTrue(router.allow_syncdb('other', Book)) 717 718 # Now check what happens if the router order is the other way around 719 router.routers = [AuthRouter(), TestRouter()] 720 721 self.assertFalse(router.allow_syncdb('default', User)) 722 self.assertTrue(router.allow_syncdb('default', Book)) 723 724 self.assertTrue(router.allow_syncdb('other', User)) 725 self.assertFalse(router.allow_syncdb('other', Book)) 726 727 680 728 def test_database_routing(self): 681 729 marty = Person.objects.using('default').create(name="Marty Alchin") 682 730 pro = Book.objects.using('default').create(title="Pro Django", … … 1046 1094 self.assertEquals(alice.get_profile().flavor, 'chocolate') 1047 1095 self.assertEquals(bob.get_profile().flavor, 'crunchy frog') 1048 1096 1097 1049 1098 class FixtureTestCase(TestCase): 1050 1099 multi_db = True 1051 1100 fixtures = ['multidb-common', 'multidb']