Reputation: 14351
I've scoured the documentation and am looking for a Django setting that disables system checks (not just silences them) in production. I have a project with 20,000+ models which are autogenerated to create RESTful endpoints. These system checks take quite some time:
https://docs.djangoproject.com/en/1.11/ref/checks/#models
Having the systems check in development is necessary, even though it causes manage.py
20-30 minutes to fire up. However, any time I publish a new version to production, the first HTTP request to a production node takes 20-30 minutes to respond as well! I'd obviously like to avoid this, because after the initial request, the site is lightning fast.
While the answer in comments below references a solution to get runserver
to come up more quickly, I'm looking for a solution for production, not our development environment.
I've looked around for a setting like DISABLED_SYSTEM_CHECKS
but have only come across SILENCED_SYSTEM_CHECKS
(see here), but that just seems to silence the output rather than not running the checks that take the time. Does such an animal exist? I'm running mod_wsgi
in production. I've seen requires_system_checks
for individual commands, but am looking for a project-wide solution. Thanks very much.
Upvotes: 2
Views: 1670
Reputation: 14351
I posted this question long ago, and never posted the solution I ended up using. The root problem was that with that many models (we're now up to 60,000!), each one would be validated on load. urls.py
contained all the end point routes, which would import the DRF ViewSets
, which in turn would load the serializers and models up-front. So what I did was create a sort of lazy loading, and we've open sourced it:
https://pypi.org/project/automagic-rest/
The key element was modifying the ViewSet
to load the model on-demand in __init__
, rather than up front:
self.model = getattr(
import_module(f"{self.python_path_name}.models.{self.schema_name}"),
f"{self.schema_name}_{self.table_name}_model",
)
You can view the full source in context here: https://github.com/wharton/automagic-rest/blob/master/automagic_rest/views.py#L53
This required developing a convention for DRF's basename
to hold the database name, app name, schema name, and model name, but it works well. The initial load time is now about 45 seconds for 60,000 models, rather than over three hours.
Upvotes: 0
Reputation: 36360
You could create a DISABLE_CHECKS
setting and force skip the check from within the check functions themselves. I noticed even if you set SILENCED_SYSTEM_CHECKS
in settings.py
, certain manage.py
commands will still run the checks (such as migrate). Here is what I use:
import logging
from django.conf import settings
from django.core.checks import Error
from django.db import connections
from django.core.cache import caches
def check_cache_connectivity(app_configs, **kwargs):
"""
Check cache
:param app_configs:
:param kwargs:
:return:
"""
errors = []
# Short circuit here, checks still ran by manage.py cmds regardless of SILENCED_SYSTEM_CHECKS
if settings.DISABLE_CHECKS:
return errors
cache_settings = settings.CACHES.keys()
for cur_cache in cache_settings:
try:
key = 'check_cache_connectivity_{}'.format(cur_cache)
caches[cur_cache].set(key, 'connectivity_ok', 30)
value = caches[cur_cache].get(key)
print("Cache '{}' connection ok, key '{}', value '{}'".format(cur_cache, key, value))
except Exception as e:
msg = "ERROR: Cache {} looks to be down. {}".format(cur_cache, e)
print(msg)
logging.exception(msg)
errors.append(
Error(
msg,
hint="Unable to connect to cache {}, set as {}. {}"
"".format(cur_cache, settings.CACHES[cur_cache], e),
obj='CACHES.{}'.format(cur_cache),
id='content_services.E002',
)
)
return errors
I use this in my build environment where I want most if not all of my custom checks ignored. Hope it helps!
Upvotes: 1