Python django.conf.settings.DATABASES Examples

The following are 30 code examples for showing how to use django.conf.settings.DATABASES(). These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example.

You may check out the related API usage on the sidebar.

You may also want to check out all available functions/classes of the module django.conf.settings , or try the search function .

Example 1
Project: coursys   Author: sfu-fas   File: panel.py    License: GNU General Public License v3.0 6 votes vote down vote up
def settings_info():
    info = []
    info.append(('Deploy mode', settings.DEPLOY_MODE))
    info.append(('Database engine', settings.DATABASES['default']['ENGINE']))
    info.append(('Authentication Backends', settings.AUTHENTICATION_BACKENDS))
    info.append(('Cache backend', settings.CACHES['default']['BACKEND']))
    info.append(('Haystack engine', settings.HAYSTACK_CONNECTIONS['default']['ENGINE']))
    info.append(('Email backend', settings.EMAIL_BACKEND))
    if hasattr(settings, 'CELERY_EMAIL') and settings.CELERY_EMAIL:
        info.append(('Celery email backend', settings.CELERY_EMAIL_BACKEND))
    if hasattr(settings, 'CELERY_BROKER_URL'):
        info.append(('Celery broker', settings.CELERY_BROKER_URL.split(':')[0]))

    DATABASES = copy.deepcopy(settings.DATABASES)
    for d in DATABASES:
        if 'PASSWORD' in DATABASES[d]:
            DATABASES[d]['PASSWORD'] = '*****'
    info.append(('DATABASES',  mark_safe('<pre>'+escape(pprint.pformat(DATABASES))+'</pre>')))

    return info 
Example 2
Project: coursys   Author: sfu-fas   File: apps.py    License: GNU General Public License v3.0 6 votes vote down vote up
def sqlite_check(app_configs, **kwargs):
    errors = []
    if 'sqlite' not in settings.DATABASES['default']['ENGINE']:
        # not using sqlite, so don't worry
        return errors

    import sqlite3
    if sqlite3.sqlite_version_info < (3, 12):
        errors.append(
            Warning(
                'SQLite version problem',
                hint='A bug is sqlite version 3.11.x causes a segfault in our tests. Upgrading to >=3.14 is suggested. This is only a warning because many things still work. Just not the tests.',
                id='coredata.E001',
            )
        )
    return errors 
Example 3
Project: ideascube   Author: ideascube   File: conftest.py    License: GNU Affero General Public License v3.0 6 votes vote down vote up
def pytest_configure(config):
    from django.conf import settings

    # This is already supposed to be the case by default, and we even tried
    # setting it explicitly anyway.
    #
    # But somehow, at the very beginning of the test suite (when running the
    # migrations or when the post_migrate signal is fired), the transient
    # database is on the filesystem (the value of NAME).
    #
    # We can't figure out why that is, it might be a bug in pytest-django, or
    # worse in django itself.
    #
    # Somehow the default database is always in memory, though.
    settings.DATABASES['transient']['TEST_NAME'] = ':memory:'

    # The documentation says not to use the ManifestStaticFilesStorage for
    # tests, and indeed if we do they fail.
    settings.STATICFILES_STORAGE = (
        'django.contrib.staticfiles.storage.StaticFilesStorage') 
Example 4
Project: GTDWeb   Author: lanbing510   File: creation.py    License: GNU General Public License v2.0 6 votes vote down vote up
def destroy_test_db(self, old_database_name, verbosity=1, keepdb=False):
        """
        Destroy a test database, prompting the user for confirmation if the
        database already exists.
        """
        self.connection.close()
        test_database_name = self.connection.settings_dict['NAME']
        if verbosity >= 1:
            test_db_repr = ''
            action = 'Destroying'
            if verbosity >= 2:
                test_db_repr = " ('%s')" % test_database_name
            if keepdb:
                action = 'Preserving'
            print("%s test database for alias '%s'%s..." % (
                action, self.connection.alias, test_db_repr))

        # if we want to preserve the database
        # skip the actual destroying piece.
        if not keepdb:
            self._destroy_test_db(test_database_name, verbosity)

        # Restore the original database name
        settings.DATABASES[self.connection.alias]["NAME"] = old_database_name
        self.connection.settings_dict["NAME"] = old_database_name 
Example 5
Project: GTDWeb   Author: lanbing510   File: base.py    License: GNU General Public License v2.0 6 votes vote down vote up
def _nodb_connection(self):
        nodb_connection = super(DatabaseWrapper, self)._nodb_connection
        try:
            nodb_connection.ensure_connection()
        except (DatabaseError, WrappedDatabaseError):
            warnings.warn(
                "Normally Django will use a connection to the 'postgres' database "
                "to avoid running initialization queries against the production "
                "database when it's not needed (for example, when running tests). "
                "Django was unable to create a connection to the 'postgres' database "
                "and will use the default database instead.",
                RuntimeWarning
            )
            settings_dict = self.settings_dict.copy()
            settings_dict['NAME'] = settings.DATABASES[DEFAULT_DB_ALIAS]['NAME']
            nodb_connection = self.__class__(
                self.settings_dict.copy(),
                alias=self.alias,
                allow_thread_sharing=False)
        return nodb_connection 
Example 6
Project: django-cachalot   Author: noripyt   File: benchmark.py    License: BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def run(self):
        for db_alias in settings.DATABASES:
            self.db_alias = db_alias
            self.db_vendor = connections[self.db_alias].vendor
            print('Benchmarking %s…' % self.db_vendor)
            for cache_alias in settings.CACHES:
                cache = caches[cache_alias]
                self.cache_name = cache.__class__.__name__[:-5].lower()
                with override_settings(CACHALOT_CACHE=cache_alias):
                    self.execute_benchmark()

        self.df = pd.DataFrame.from_records(self.data)
        if not os.path.exists(RESULTS_PATH):
            os.mkdir(RESULTS_PATH)
        self.df.to_csv(os.path.join(RESULTS_PATH, 'data.csv'))

        self.xlim = (0, self.df['time'].max() * 1.01)
        self.output('db')
        self.output('cache') 
Example 7
Project: django-cachalot   Author: noripyt   File: panels.py    License: BSD 3-Clause "New" or "Revised" License 6 votes vote down vote up
def collect_invalidations(self):
        models = apps.get_models()
        data = defaultdict(list)
        cache = cachalot_caches.get_cache()
        for db_alias in settings.DATABASES:
            get_table_cache_key = cachalot_settings.CACHALOT_TABLE_KEYGEN
            model_cache_keys = {
                get_table_cache_key(db_alias, model._meta.db_table): model
                for model in models}
            for cache_key, timestamp in cache.get_many(
                    model_cache_keys.keys()).items():
                invalidation = datetime.fromtimestamp(timestamp)
                model = model_cache_keys[cache_key]
                data[db_alias].append(
                    (model._meta.app_label, model.__name__, invalidation))
                if self.last_invalidation is None \
                        or invalidation > self.last_invalidation:
                    self.last_invalidation = invalidation
            data[db_alias].sort(key=lambda row: row[2], reverse=True)
        self.record_stats({'invalidations_per_db': data.items()}) 
Example 8
Project: bioforum   Author: reBiocoder   File: creation.py    License: MIT License 6 votes vote down vote up
def _switch_to_test_user(self, parameters):
        """
        Switch to the user that's used for creating the test database.

        Oracle doesn't have the concept of separate databases under the same
        user, so a separate user is used; see _create_test_db(). The main user
        is also needed for cleanup when testing is completed, so save its
        credentials in the SAVED_USER/SAVED_PASSWORD key in the settings dict.
        """
        real_settings = settings.DATABASES[self.connection.alias]
        real_settings['SAVED_USER'] = self.connection.settings_dict['SAVED_USER'] = \
            self.connection.settings_dict['USER']
        real_settings['SAVED_PASSWORD'] = self.connection.settings_dict['SAVED_PASSWORD'] = \
            self.connection.settings_dict['PASSWORD']
        real_test_settings = real_settings['TEST']
        test_settings = self.connection.settings_dict['TEST']
        real_test_settings['USER'] = real_settings['USER'] = test_settings['USER'] = \
            self.connection.settings_dict['USER'] = parameters['user']
        real_settings['PASSWORD'] = self.connection.settings_dict['PASSWORD'] = parameters['password'] 
Example 9
Project: bioforum   Author: reBiocoder   File: base.py    License: MIT License 6 votes vote down vote up
def get_connection_params(self):
        settings_dict = self.settings_dict
        # None may be used to connect to the default 'postgres' db
        if settings_dict['NAME'] == '':
            raise ImproperlyConfigured(
                "settings.DATABASES is improperly configured. "
                "Please supply the NAME value.")
        conn_params = {
            'database': settings_dict['NAME'] or 'postgres',
        }
        conn_params.update(settings_dict['OPTIONS'])
        conn_params.pop('isolation_level', None)
        if settings_dict['USER']:
            conn_params['user'] = settings_dict['USER']
        if settings_dict['PASSWORD']:
            conn_params['password'] = settings_dict['PASSWORD']
        if settings_dict['HOST']:
            conn_params['host'] = settings_dict['HOST']
        if settings_dict['PORT']:
            conn_params['port'] = settings_dict['PORT']
        return conn_params 
Example 10
Project: bioforum   Author: reBiocoder   File: base.py    License: MIT License 6 votes vote down vote up
def _nodb_connection(self):
        nodb_connection = super()._nodb_connection
        try:
            nodb_connection.ensure_connection()
        except (Database.DatabaseError, WrappedDatabaseError):
            warnings.warn(
                "Normally Django will use a connection to the 'postgres' database "
                "to avoid running initialization queries against the production "
                "database when it's not needed (for example, when running tests). "
                "Django was unable to create a connection to the 'postgres' database "
                "and will use the default database instead.",
                RuntimeWarning
            )
            settings_dict = self.settings_dict.copy()
            settings_dict['NAME'] = settings.DATABASES[DEFAULT_DB_ALIAS]['NAME']
            nodb_connection = self.__class__(
                self.settings_dict.copy(),
                alias=self.alias,
                allow_thread_sharing=False)
        return nodb_connection 
Example 11
Project: django-twitter-stream   Author: michaelbrooks   File: models.py    License: MIT License 6 votes vote down vote up
def count_approx(cls):
        """
        Get the approximate number of tweets.
        Executes quickly, even on large InnoDB tables.
        """
        if django_settings.DATABASES['default']['ENGINE'].endswith('mysql'):
            query = "SHOW TABLE STATUS WHERE Name = %s"
            cursor = connection.cursor()
            cursor.execute(query, [cls._meta.db_table])

            desc = cursor.description
            row = cursor.fetchone()
            row = dict(zip([col[0].lower() for col in desc], row))

            return int(row['rows'])
        else:
            return cls.objects.count() 
Example 12
Project: zappa-django-utils   Author: Miserlou   File: drop_pg_db.py    License: MIT License 6 votes vote down vote up
def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS('Starting to drop DB..'))

        dbname = settings.DATABASES['default']['NAME']
        user = settings.DATABASES['default']['USER']
        password = settings.DATABASES['default']['PASSWORD']
        host = settings.DATABASES['default']['HOST']

        self.stdout.write(self.style.SUCCESS('Connecting to host..'))
        con = connect(dbname='postgres', user=user, host=host, password=password)
        con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

        self.stdout.write(self.style.SUCCESS("Dropping database '{}'".format(dbname)))
        cur = con.cursor()
        cur.execute('DROP DATABASE ' + dbname)
        cur.close()

        con.close()

        self.stdout.write(self.style.SUCCESS('All done!')) 
Example 13
Project: zappa-django-utils   Author: Miserlou   File: create_pg_db.py    License: MIT License 6 votes vote down vote up
def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS('Starting DB creation..'))

        dbname = settings.DATABASES['default']['NAME']
        user = settings.DATABASES['default']['USER']
        password = settings.DATABASES['default']['PASSWORD']
        host = settings.DATABASES['default']['HOST']

        self.stdout.write(self.style.SUCCESS('Connecting to host..'))
        con = connect(dbname='postgres', user=user, host=host, password=password)
        con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

        self.stdout.write(self.style.SUCCESS('Creating database'))
        cur = con.cursor()
        cur.execute('CREATE DATABASE ' + dbname)
        cur.close()

        con.close()

        self.stdout.write(self.style.SUCCESS('All done!')) 
Example 14
Project: zappa-django-utils   Author: Miserlou   File: create_mysql_db.py    License: MIT License 6 votes vote down vote up
def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS('Starting db creation'))

        dbname = options.get('db_name') or settings.DATABASES['default']['NAME']
        user = options.get('user') or settings.DATABASES['default']['USER']
        password = options.get('password') or settings.DATABASES['default']['PASSWORD']
        host = settings.DATABASES['default']['HOST']

        con = db.connect(user=user, host=host, password=password)
        cur = con.cursor()
        cur.execute(f'CREATE DATABASE {dbname}')
        cur.execute(f'ALTER DATABASE `{dbname}` CHARACTER SET utf8')
        cur.close()
        con.close()

        self.stdout.write(self.style.SUCCESS('All Done')) 
Example 15
Project: zappa-django-utils   Author: Miserlou   File: drop_pg_schema.py    License: MIT License 6 votes vote down vote up
def handle(self, *args, **options):
        self.stdout.write(self.style.SUCCESS('Starting schema deletion...'))

        dbname = settings.DATABASES['default']['NAME']
        user = settings.DATABASES['default']['USER']
        password = settings.DATABASES['default']['PASSWORD']
        host = settings.DATABASES['default']['HOST']

        con = connect(dbname=dbname, user=user, host=host, password=password)

        self.stdout.write(self.style.SUCCESS('Removing schema {schema} from database {dbname}'
                                             .format(schema=settings.SCHEMA, dbname=dbname)))
        con.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)

        cur = con.cursor()
        cur.execute('DROP SCHEMA {schema} CASCADE;'.format(schema=settings.SCHEMA))
        cur.close()

        con.close()

        self.stdout.write(self.style.SUCCESS('All done.')) 
Example 16
Project: zulip   Author: zulip   File: test_runner.py    License: Apache License 2.0 6 votes vote down vote up
def setup_test_environment(self, *args: Any, **kwargs: Any) -> Any:
        settings.DATABASES['default']['NAME'] = settings.BACKEND_DATABASE_TEMPLATE
        # We create/destroy the test databases in run_tests to avoid
        # duplicate work when running in parallel mode.

        # Write the template database ids to a file that we can
        # reference for cleaning them up if they leak.
        filepath = os.path.join(get_dev_uuid_var_path(),
                                TEMPLATE_DATABASE_DIR,
                                get_database_id())
        os.makedirs(os.path.dirname(filepath), exist_ok=True)
        with open(filepath, "w") as f:
            if self.parallel > 1:
                for index in range(self.parallel):
                    f.write(get_database_id(index + 1) + "\n")
            else:
                f.write(get_database_id() + "\n")

        # Check if we are in serial mode to avoid unnecessarily making a directory.
        # We add "worker_0" in the path for consistency with parallel mode.
        if self.parallel == 1:
            initialize_worker_path(0)

        return super().setup_test_environment(*args, **kwargs) 
Example 17
Project: urbanfootprint   Author: CalthorpeAnalytics   File: information_schema.py    License: GNU General Public License v3.0 6 votes vote down vote up
def get_table_description(self, cursor, full_table_name):
        """
            Override the parent method to take schemas into account, sigh
        :param cursor:
        :param full_table_name:
        :return:
        """
        schema, table = parse_schema_and_table(full_table_name)
        # conn = psycopg2.connect(**pg_connection_parameters(settings.DATABASES['default']))
        # conn.set_isolation_level(psycopg2.extensions.ISOLATION_LEVEL_AUTOCOMMIT)
        # cursor = conn.cursor()
        cursor.execute("""
            SELECT column_name, is_nullable
            FROM information_schema.columns
            WHERE table_name = %s and table_schema = %s""", [table, schema])
        null_map = dict(cursor.fetchall())
        cursor.execute('SELECT * FROM "{schema}"."{table}" LIMIT 1'.format(schema=schema, table=table))
        return [tuple([item for item in line[:6]] + [null_map[line[0]]==u'YES'])
                for line in cursor.description] 
Example 18
Project: Servo   Author: fpsw   File: dbrestore.py    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
def handle(self, *args, **options):
          if len(args) < 1:
               print 'Usage: dbrestore file'
               sys.exit(1)

          db = settings.DATABASES['default']
          pg_restore = subprocess.check_output(['which', 'pg_restore']).strip()
          subprocess.call([pg_restore, '-d', db['NAME'], '-O', '-x', '-U', db['USER'],
                          args[0]], env={'PGPASSWORD': db['PASSWORD']}) 
Example 19
Project: Servo   Author: fpsw   File: dbbackup.py    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
def handle(self, *args, **options):
        db  = settings.DATABASES['default']
        fn = '%s_%s.pgdump' % (db['NAME'], strftime('%Y%m%d_%H%I'))
        if not os.path.exists(settings.BACKUP_DIR):
            os.mkdir(settings.BACKUP_DIR)
        fn = os.path.join(settings.BACKUP_DIR, fn)
        env = {'PATH': os.getenv('PATH'), 'PGPASSWORD': db['PASSWORD']}
        subprocess.call(['pg_dump', '-Fc', db['NAME'], '-U',
                        db['USER'], '-f' , fn], env=env) 
Example 20
Project: Servo   Author: fpsw   File: dumpdb.py    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
def handle(self, *args, **options):
        s = settings.DATABASES['default']
        db, user, pw = s['NAME'], s['USER'], s['PASSWORD']
        fname  = datetime.now().strftime('%Y%m%d_%H%M') + '.pgdump'
        
        if not os.path.exists(settings.BACKUP_DIR):
            os.mkdir(settings.BACKUP_DIR)

        path = os.path.join(settings.BACKUP_DIR, fname)
        os.putenv('PGPASSWORD', pw)
        subprocess.call(['pg_dump', '-Fc',  db, '-U', user, '-f', path]) 
Example 21
Project: GTDWeb   Author: lanbing510   File: utils.py    License: GNU General Public License v2.0 5 votes vote down vote up
def __init__(self, databases=None):
        """
        databases is an optional dictionary of database definitions (structured
        like settings.DATABASES).
        """
        self._databases = databases
        self._connections = local() 
Example 22
Project: GTDWeb   Author: lanbing510   File: utils.py    License: GNU General Public License v2.0 5 votes vote down vote up
def databases(self):
        if self._databases is None:
            self._databases = settings.DATABASES
        if self._databases == {}:
            self._databases = {
                DEFAULT_DB_ALIAS: {
                    'ENGINE': 'django.db.backends.dummy',
                },
            }
        if DEFAULT_DB_ALIAS not in self._databases:
            raise ImproperlyConfigured("You must define a '%s' database" % DEFAULT_DB_ALIAS)
        return self._databases 
Example 23
Project: GTDWeb   Author: lanbing510   File: creation.py    License: GNU General Public License v2.0 5 votes vote down vote up
def test_db_signature(self):
        """
        Returns a tuple with elements of self.connection.settings_dict (a
        DATABASES setting value) that uniquely identify a database
        accordingly to the RDBMS particularities.
        """
        settings_dict = self.connection.settings_dict
        return (
            settings_dict['HOST'],
            settings_dict['PORT'],
            settings_dict['ENGINE'],
            settings_dict['NAME']
        ) 
Example 24
Project: GTDWeb   Author: lanbing510   File: base.py    License: GNU General Public License v2.0 5 votes vote down vote up
def get_connection_params(self):
        settings_dict = self.settings_dict
        if not settings_dict['NAME']:
            from django.core.exceptions import ImproperlyConfigured
            raise ImproperlyConfigured(
                "settings.DATABASES is improperly configured. "
                "Please supply the NAME value.")
        kwargs = {
            'database': settings_dict['NAME'],
            'detect_types': Database.PARSE_DECLTYPES | Database.PARSE_COLNAMES,
        }
        kwargs.update(settings_dict['OPTIONS'])
        # Always allow the underlying SQLite connection to be shareable
        # between multiple threads. The safe-guarding will be handled at a
        # higher level by the `BaseDatabaseWrapper.allow_thread_sharing`
        # property. This is necessary as the shareability is disabled by
        # default in pysqlite and it cannot be changed once a connection is
        # opened.
        if 'check_same_thread' in kwargs and kwargs['check_same_thread']:
            warnings.warn(
                'The `check_same_thread` option was provided and set to '
                'True. It will be overridden with False. Use the '
                '`DatabaseWrapper.allow_thread_sharing` property instead '
                'for controlling thread shareability.',
                RuntimeWarning
            )
        kwargs.update({'check_same_thread': False})
        if self.features.can_share_in_memory_db:
            kwargs.update({'uri': True})
        return kwargs 
Example 25
Project: django_migration_testcase   Author: plumdog   File: base.py    License: MIT License 5 votes vote down vote up
def idempotent_transaction(func):
    if django.VERSION < (1, 7,) or django.VERSION >= (2, 0) and settings.DATABASES['default']['ENGINE'] == 'django.db.backends.sqlite3':
        return func
    else:
        @functools.wraps(func)
        def func_wrapper(*args, **kwargs):
            with transaction.atomic():
                sp = transaction.savepoint()
                try:
                    func(*args, **kwargs)
                    transaction.savepoint_rollback(sp)
                except BaseException:
                    raise
        return func_wrapper 
Example 26
Project: kobo-predict   Author: awemulya   File: query.py    License: BSD 2-Clause "Simplified" License 5 votes vote down vote up
def using_postgres():
    return settings.DATABASES[
        'default']['ENGINE'] == 'django.db.backends.postgresql_psycopg2' 
Example 27
Project: django-user-activity-log   Author: scailer   File: models.py    License: MIT License 5 votes vote down vote up
def createdb(sender, using, **kwargs):
        db = settings.DATABASES[conf.LOG_DB_KEY]['NAME']
        with connection.cursor() as cursor:
            try:
                cursor.execute("CREATE DATABASE {}".format(db))
            except ProgrammingError:
                pass

        if using == 'default':
            call_command('migrate', database=conf.LOG_DB_KEY) 
Example 28
Project: django-user-activity-log   Author: scailer   File: models.py    License: MIT License 5 votes vote down vote up
def createdb(sender, using, **kwargs):
        db = settings.DATABASES[conf.LOG_DB_KEY]['NAME']
        with connection.cursor() as cursor:
            try:
                cursor.execute("CREATE DATABASE {}".format(db))
            except ProgrammingError:
                pass

        if using == 'default':
            call_command('migrate', database=conf.LOG_DB_KEY) 
Example 29
Project: django-cachalot   Author: noripyt   File: api.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def _cache_db_tables_iterator(tables, cache_alias, db_alias):
    no_tables = not tables
    cache_aliases = settings.CACHES if cache_alias is None else (cache_alias,)
    db_aliases = settings.DATABASES if db_alias is None else (db_alias,)
    for db_alias in db_aliases:
        if no_tables:
            tables = connections[db_alias].introspection.table_names()
        if tables:
            for cache_alias in cache_aliases:
                yield cache_alias, db_alias, tables 
Example 30
Project: django-cachalot   Author: noripyt   File: api.py    License: BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def get_last_invalidation(*tables_or_models, **kwargs):
    """
    Returns the timestamp of the most recent invalidation of the given
    ``tables_or_models``.  If ``tables_or_models`` is not specified,
    all tables found in the database (including those outside Django) are used.

    If ``cache_alias`` is specified, it only fetches invalidations
    in this cache, otherwise invalidations in all caches are fetched.

    If ``db_alias`` is specified, it only fetches invalidations
    for this database, otherwise invalidations for all databases are fetched.

    :arg tables_or_models: SQL tables names, models or models lookups
                           (or a combination)
    :type tables_or_models: tuple of strings or models
    :arg cache_alias: Alias from the Django ``CACHES`` setting
    :type cache_alias: string or NoneType
    :arg db_alias: Alias from the Django ``DATABASES`` setting
    :type db_alias: string or NoneType
    :returns: The timestamp of the most recent invalidation
    :rtype: float
    """
    # TODO: Replace with positional arguments when we drop Python 2 support.
    cache_alias = kwargs.pop('cache_alias', None)
    db_alias = kwargs.pop('db_alias', None)
    for k in kwargs:
        raise TypeError("get_last_invalidation() got an unexpected "
                        "keyword argument '%s'" % k)

    last_invalidation = 0.0
    for cache_alias, db_alias, tables in _cache_db_tables_iterator(
            list(_get_tables(tables_or_models)), cache_alias, db_alias):
        get_table_cache_key = cachalot_settings.CACHALOT_TABLE_KEYGEN
        table_cache_keys = [get_table_cache_key(db_alias, t) for t in tables]
        invalidations = cachalot_caches.get_cache(
            cache_alias, db_alias).get_many(table_cache_keys).values()
        if invalidations:
            current_last_invalidation = max(invalidations)
            if current_last_invalidation > last_invalidation:
                last_invalidation = current_last_invalidation
    return last_invalidation