def test_should_return_empty_strings_if_read_default_file_option_is_missing( self): dbinfo = {} result = parse_mysql_cnf(dbinfo) self.assertEqual(result, ('', '', '', '', ''))
def test_should_return_empty_strings_if_NoSectionError_exception_occured( self): my_cnf_path = os.path.join(self.tmpdir, 'my.cnf') with open(my_cnf_path, 'w') as f: f.write("") dbinfo = { 'ENGINE': 'django.db.backends.mysql', 'OPTIONS': { 'read_default_file': my_cnf_path, } } result = parse_mysql_cnf(dbinfo) self.assertEqual(result, ('', '', '', '', ''))
def test_should_parse_my_cnf_and_retun_connection_settings(self): my_cnf_path = os.path.join(self.tmpdir, 'my.cnf') with open(my_cnf_path, 'w') as f: f.write("""[client] database = test_name user = test_user password = test_password host = localhost port = 3306 socket = /var/lib/mysqld/mysql.sock """) dbinfo = { 'ENGINE': 'django.db.backends.mysql', 'OPTIONS': { 'read_default_file': my_cnf_path, } } result = parse_mysql_cnf(dbinfo) self.assertEqual(result, ('test_user', 'test_password', 'test_name', '/var/lib/mysqld/mysql.sock', '3306'))
def handle(self, *args, **options): """ Drop test database for this project. """ if args: raise CommandError("reset_db takes no arguments") router = options.get('router') dbinfo = settings.DATABASES.get(router) if dbinfo is None: raise CommandError("Unknown database router %s" % router) engine = dbinfo.get('ENGINE').split('.')[-1] user = password = database_name = database_host = database_port = '' if engine == 'mysql': (user, password, database_name, database_host, database_port) = parse_mysql_cnf(dbinfo) user = options.get('user') or dbinfo.get('USER') or user password = options.get('password') or dbinfo.get( 'PASSWORD') or password try: database_name = dbinfo['TEST']['NAME'] except KeyError: database_name = None if database_name is None: database_name = TEST_DATABASE_PREFIX + (options.get('dbname') or dbinfo.get('NAME')) if database_name is None or database_name == '': raise CommandError( "You need to specify DATABASE_NAME in your Django settings file." ) database_host = dbinfo.get('HOST') or database_host database_port = dbinfo.get('PORT') or database_port verbosity = int(options.get('verbosity', 1)) if options.get('interactive'): confirm = input(""" You have requested to drop the test database. This will IRREVERSIBLY DESTROY ALL data in the database "%s". Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """ % (database_name, )) else: confirm = 'yes' if confirm != 'yes': print("Reset cancelled.") return if engine in ('sqlite3', 'spatialite'): import os try: logging.info("Unlinking %s database" % engine) if os.path.isfile(database_name): os.unlink(database_name) except OSError: pass elif engine in ('mysql', ): import MySQLdb as Database kwargs = { 'user': user, 'passwd': password, } if database_host.startswith('/'): kwargs['unix_socket'] = database_host else: kwargs['host'] = database_host if database_port: kwargs['port'] = int(database_port) connection = Database.connect(**kwargs) drop_query = 'DROP DATABASE IF EXISTS `%s`' % database_name logging.info('Executing: "' + drop_query + '"') connection.query(drop_query) elif engine in ('postgresql', 'postgresql_psycopg2', 'postgis'): if engine == 'postgresql': import psycopg as Database # NOQA elif engine in ('postgresql_psycopg2', 'postgis'): import psycopg2 as Database # NOQA conn_params = {'database': 'template1'} if user: conn_params['user'] = user if password: conn_params['password'] = password if database_host: conn_params['host'] = database_host if database_port: conn_params['port'] = database_port connection = Database.connect(**conn_params) connection.set_isolation_level(0) # autocommit false cursor = connection.cursor() drop_query = "DROP DATABASE IF EXISTS \"%s\";" % database_name logging.info('Executing: "' + drop_query + '"') try: cursor.execute(drop_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) else: raise CommandError("Unknown database engine %s" % engine) if verbosity >= 2 or options.get('interactive'): print("Reset successful.")
def handle(self, *args, **options): """ Resets the database for this project. Note: Transaction wrappers are in reverse as a work around for autocommit, anybody know how to do this the right way? """ if args: raise CommandError("reset_db takes no arguments") router = options['router'] dbinfo = settings.DATABASES.get(router) if dbinfo is None: raise CommandError("Unknown database router %s" % router) engine = dbinfo.get('ENGINE').split('.')[-1] user = password = database_name = database_host = database_port = '' if engine == 'mysql': (user, password, database_name, database_host, database_port) = parse_mysql_cnf(dbinfo) user = options['user'] or dbinfo.get('USER') or user password = options['password'] or dbinfo.get('PASSWORD') or password owner = options['owner'] or user database_name = options['dbname'] or dbinfo.get('NAME') or database_name if database_name == '': raise CommandError("You need to specify DATABASE_NAME in your Django settings file.") database_host = dbinfo.get('HOST') or database_host database_port = dbinfo.get('PORT') or database_port verbosity = options["verbosity"] if options['interactive']: confirm = input(""" You have requested a database reset. This will IRREVERSIBLY DESTROY ALL data in the database "%s". Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """ % (database_name,)) else: confirm = 'yes' if confirm != 'yes': print("Reset cancelled.") return if engine in ('sqlite3', 'spatialite'): import os try: logging.info("Unlinking %s database" % engine) os.unlink(database_name) except OSError: pass elif engine in ('mysql',): import MySQLdb as Database kwargs = { 'user': user, 'passwd': password, } if database_host.startswith('/'): kwargs['unix_socket'] = database_host else: kwargs['host'] = database_host if database_port: kwargs['port'] = int(database_port) connection = Database.connect(**kwargs) drop_query = 'DROP DATABASE IF EXISTS `%s`' % database_name utf8_support = '' if options['no_utf8_support'] else 'CHARACTER SET utf8' create_query = 'CREATE DATABASE `%s` %s' % (database_name, utf8_support) logging.info('Executing... "' + drop_query + '"') connection.query(drop_query) logging.info('Executing... "' + create_query + '"') connection.query(create_query) elif engine in ('postgresql', 'postgresql_psycopg2', 'postgis'): import psycopg2 as Database # NOQA conn_params = {'database': 'template1'} if user: conn_params['user'] = user if password: conn_params['password'] = password if database_host: conn_params['host'] = database_host if database_port: conn_params['port'] = database_port connection = Database.connect(**conn_params) connection.set_isolation_level(0) # autocommit false cursor = connection.cursor() if options['close_sessions']: close_sessions_query = """ SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE pg_stat_activity.datname = '%s'; """ % database_name logging.info('Executing... "' + close_sessions_query.strip() + '"') try: cursor.execute(close_sessions_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) drop_query = "DROP DATABASE \"%s\";" % database_name logging.info('Executing... "' + drop_query + '"') try: cursor.execute(drop_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) create_query = "CREATE DATABASE \"%s\"" % database_name if owner: create_query += " WITH OWNER = \"%s\" " % owner create_query += " ENCODING = 'UTF8'" if settings.DEFAULT_TABLESPACE: create_query += ' TABLESPACE = %s;' % settings.DEFAULT_TABLESPACE else: create_query += ';' logging.info('Executing... "' + create_query + '"') cursor.execute(create_query) else: raise CommandError("Unknown database engine %s" % engine) if verbosity >= 2 or options['interactive']: print("Reset successful.")
def handle(self, *args, **options): """Drop test database for this project.""" database = options['database'] if options['router'] != DEFAULT_DB_ALIAS: warnings.warn("--router is deprecated. You should use --database.", RemovedInNextVersionWarning, stacklevel=2) database = options['router'] dbinfo = settings.DATABASES.get(database) if dbinfo is None: raise CommandError("Unknown database %s" % database) engine = dbinfo.get('ENGINE') user = password = database_name = database_host = database_port = '' if engine == 'mysql': (user, password, database_name, database_host, database_port) = parse_mysql_cnf(dbinfo) user = options['user'] or dbinfo.get('USER') or user password = options['password'] or dbinfo.get('PASSWORD') or password try: database_name = dbinfo['TEST']['NAME'] except KeyError: database_name = None if database_name is None: database_name = TEST_DATABASE_PREFIX + (options['dbname'] or dbinfo.get('NAME')) if database_name is None or database_name == '': raise CommandError( "You need to specify DATABASE_NAME in your Django settings file." ) database_host = dbinfo.get('HOST') or database_host database_port = dbinfo.get('PORT') or database_port verbosity = options["verbosity"] if options['interactive']: confirm = input(""" You have requested to drop all test databases. This will IRREVERSIBLY DESTROY ALL data in the database "{db_name}" and all cloned test databases generated via the "--parallel" flag (these are sequentially named "{db_name}_1", "{db_name}_2", etc.). Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """.format(db_name=database_name)) else: confirm = 'yes' if confirm != 'yes': print("Reset cancelled.") return def get_database_names(formatter): """ Return a generator of all possible test database names. e.g., 'test_foo', 'test_foo_1', test_foo_2', etc. formatter: func returning a clone db name given the primary db name and the clone's number, e.g., 'test_foo_1' for mysql/postgres, and 'test_foo_1..sqlite3' for sqlite (re: double dots, see comments). """ yield database_name yield from (formatter(database_name, n) for n in count(1)) if engine in SQLITE_ENGINES: # By default all sqlite test databases are created in memory. # There will only be database files to delete if the developer has # specified a test database name, which forces files to be written # to disk. logging.info("Unlinking %s databases" % engine) def format_filename(name, number): filename, ext = os.path.splitext(name) # Since splitext() includes the dot in 'ext', the inclusion of # the dot in the format string below is incorrect and creates a # double dot. Django makes this mistake, so it must be # replicated here. If fixed in Django, this code should be # updated accordingly. # Reference: https://code.djangoproject.com/ticket/32582 return '{}_{}.{}'.format(filename, number, ext) try: for db_name in get_database_names(format_filename): if not os.path.isfile(db_name): break logging.info('Unlinking database named "%s"' % db_name) os.unlink(db_name) except OSError: return elif engine in MYSQL_ENGINES: import MySQLdb as Database kwargs = { 'user': user, 'passwd': password, } if database_host.startswith('/'): kwargs['unix_socket'] = database_host else: kwargs['host'] = database_host if database_port: kwargs['port'] = int(database_port) connection = Database.connect(**kwargs) cursor = connection.cursor() for db_name in get_database_names('{}_{}'.format): exists_query = \ "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='%s';" \ % db_name row_count = cursor.execute(exists_query) if row_count < 1: break drop_query = 'DROP DATABASE IF EXISTS `%s`' % db_name logging.info('Executing: "' + drop_query + '"') cursor.execute(drop_query) elif engine in POSTGRESQL_ENGINES: import psycopg2 as Database # NOQA conn_params = {'database': 'template1'} if user: conn_params['user'] = user if password: conn_params['password'] = password if database_host: conn_params['host'] = database_host if database_port: conn_params['port'] = database_port connection = Database.connect(**conn_params) connection.set_isolation_level(0) # autocommit false cursor = connection.cursor() for db_name in get_database_names('{}_{}'.format): exists_query = "SELECT datname FROM pg_catalog.pg_database WHERE datname='%s';" \ % db_name try: cursor.execute(exists_query) # NOTE: Unlike MySQLdb, the psycopg2 cursor does not return the row count # however both cursors provide it as a property if cursor.rowcount < 1: break drop_query = "DROP DATABASE IF EXISTS \"%s\";" % db_name logging.info('Executing: "' + drop_query + '"') cursor.execute(drop_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) return else: raise CommandError("Unknown database engine %s" % engine) if verbosity >= 2 or options['interactive']: print("Reset successful.")
def handle(self, *args, **options): """ Drop test database for this project. """ if args: raise CommandError("reset_db takes no arguments") router = options.get('router') dbinfo = settings.DATABASES.get(router) if dbinfo is None: raise CommandError("Unknown database router %s" % router) engine = dbinfo.get('ENGINE').split('.')[-1] user = password = database_name = database_host = database_port = '' if engine == 'mysql': (user, password, database_name, database_host, database_port) = parse_mysql_cnf(dbinfo) user = options.get('user') or dbinfo.get('USER') or user password = options.get('password') or dbinfo.get('PASSWORD') or password try: database_name = dbinfo['TEST']['NAME'] except KeyError: database_name = None if database_name is None: database_name = TEST_DATABASE_PREFIX + (options.get('dbname') or dbinfo.get('NAME')) if database_name is None or database_name == '': raise CommandError("You need to specify DATABASE_NAME in your Django settings file.") database_host = dbinfo.get('HOST') or database_host database_port = dbinfo.get('PORT') or database_port verbosity = int(options.get('verbosity', 1)) if options.get('interactive'): confirm = input(""" You have requested to drop the test database. This will IRREVERSIBLY DESTROY ALL data in the database "%s". Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """ % (database_name,)) else: confirm = 'yes' if confirm != 'yes': print("Reset cancelled.") return if engine in ('sqlite3', 'spatialite'): import os try: logging.info("Unlinking %s database" % engine) if os.path.isfile(database_name): os.unlink(database_name) except OSError: pass elif engine in ('mysql',): import MySQLdb as Database kwargs = { 'user': user, 'passwd': password, } if database_host.startswith('/'): kwargs['unix_socket'] = database_host else: kwargs['host'] = database_host if database_port: kwargs['port'] = int(database_port) connection = Database.connect(**kwargs) drop_query = 'DROP DATABASE IF EXISTS `%s`' % database_name logging.info('Executing: "' + drop_query + '"') connection.query(drop_query) elif engine in ('postgresql', 'postgresql_psycopg2', 'postgis'): if engine == 'postgresql': import psycopg as Database # NOQA elif engine in ('postgresql_psycopg2', 'postgis'): import psycopg2 as Database # NOQA conn_params = {'database': 'template1'} if user: conn_params['user'] = user if password: conn_params['password'] = password if database_host: conn_params['host'] = database_host if database_port: conn_params['port'] = database_port connection = Database.connect(**conn_params) connection.set_isolation_level(0) # autocommit false cursor = connection.cursor() drop_query = "DROP DATABASE IF EXISTS \"%s\";" % database_name logging.info('Executing: "' + drop_query + '"') try: cursor.execute(drop_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) else: raise CommandError("Unknown database engine %s" % engine) if verbosity >= 2 or options.get('interactive'): print("Reset successful.")
def handle(self, *args, **options): """Drop test database for this project.""" database = options['database'] if options['router'] != DEFAULT_DB_ALIAS: warnings.warn("--router is deprecated. You should use --database.", RemovedInNextVersionWarning, stacklevel=2) database = options['router'] dbinfo = settings.DATABASES.get(database) if dbinfo is None: raise CommandError("Unknown database %s" % database) engine = dbinfo.get('ENGINE') user = password = database_name = database_host = database_port = '' if engine == 'mysql': (user, password, database_name, database_host, database_port) = parse_mysql_cnf(dbinfo) user = options['user'] or dbinfo.get('USER') or user password = options['password'] or dbinfo.get('PASSWORD') or password try: database_name = dbinfo['TEST']['NAME'] except KeyError: database_name = None if database_name is None: database_name = TEST_DATABASE_PREFIX + (options['dbname'] or dbinfo.get('NAME')) if database_name is None or database_name == '': raise CommandError( "You need to specify DATABASE_NAME in your Django settings file." ) database_host = dbinfo.get('HOST') or database_host database_port = dbinfo.get('PORT') or database_port verbosity = options["verbosity"] if options['interactive']: confirm = input(""" You have requested to drop the test database. This will IRREVERSIBLY DESTROY ALL data in the database "%s". Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """ % (database_name, )) else: confirm = 'yes' if confirm != 'yes': print("Reset cancelled.") return if engine in SQLITE_ENGINES: try: logging.info("Unlinking %s database" % engine) if os.path.isfile(database_name): os.unlink(database_name) except OSError: return elif engine in MYSQL_ENGINES: import MySQLdb as Database kwargs = { 'user': user, 'passwd': password, } if database_host.startswith('/'): kwargs['unix_socket'] = database_host else: kwargs['host'] = database_host if database_port: kwargs['port'] = int(database_port) connection = Database.connect(**kwargs) drop_query = 'DROP DATABASE IF EXISTS `%s`' % database_name logging.info('Executing: "' + drop_query + '"') connection.query(drop_query) elif engine in POSTGRESQL_ENGINES: import psycopg2 as Database # NOQA conn_params = {'database': 'template1'} if user: conn_params['user'] = user if password: conn_params['password'] = password if database_host: conn_params['host'] = database_host if database_port: conn_params['port'] = database_port connection = Database.connect(**conn_params) connection.set_isolation_level(0) # autocommit false cursor = connection.cursor() drop_query = "DROP DATABASE IF EXISTS \"%s\";" % database_name logging.info('Executing: "' + drop_query + '"') try: cursor.execute(drop_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) return else: raise CommandError("Unknown database engine %s" % engine) if verbosity >= 2 or options['interactive']: print("Reset successful.")
def handle(self, *args, **options): """ Drop test database for this project. """ if args: raise CommandError("reset_db takes no arguments") router = options.get("router") dbinfo = settings.DATABASES.get(router) if dbinfo is None: raise CommandError("Unknown database router %s" % router) engine = dbinfo.get("ENGINE").split(".")[-1] user = password = database_name = database_host = database_port = "" if engine == "mysql": (user, password, database_name, database_host, database_port) = parse_mysql_cnf(dbinfo) user = options.get("user") or dbinfo.get("USER") or user password = options.get("password") or dbinfo.get("PASSWORD") or password try: database_name = dbinfo["TEST"]["NAME"] except KeyError: database_name = None if database_name is None: database_name = TEST_DATABASE_PREFIX + (options.get("dbname") or dbinfo.get("NAME")) if database_name is None or database_name == "": raise CommandError("You need to specify DATABASE_NAME in your Django settings file.") database_host = dbinfo.get("HOST") or database_host database_port = dbinfo.get("PORT") or database_port verbosity = int(options.get("verbosity", 1)) if options.get("interactive"): confirm = input( """ You have requested to drop the test database. This will IRREVERSIBLY DESTROY ALL data in the database "%s". Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """ % (database_name,) ) else: confirm = "yes" if confirm != "yes": print("Reset cancelled.") return if engine in ("sqlite3", "spatialite"): import os try: logging.info("Unlinking %s database" % engine) if os.path.isfile(database_name): os.unlink(database_name) except OSError: pass elif engine in ("mysql",): import MySQLdb as Database kwargs = {"user": user, "passwd": password} if database_host.startswith("/"): kwargs["unix_socket"] = database_host else: kwargs["host"] = database_host if database_port: kwargs["port"] = int(database_port) connection = Database.connect(**kwargs) drop_query = "DROP DATABASE IF EXISTS `%s`" % database_name logging.info('Executing: "' + drop_query + '"') connection.query(drop_query) elif engine in ("postgresql", "postgresql_psycopg2", "postgis"): if engine == "postgresql": import psycopg as Database # NOQA elif engine in ("postgresql_psycopg2", "postgis"): import psycopg2 as Database # NOQA conn_params = {"database": "template1"} if user: conn_params["user"] = user if password: conn_params["password"] = password if database_host: conn_params["host"] = database_host if database_port: conn_params["port"] = database_port connection = Database.connect(**conn_params) connection.set_isolation_level(0) # autocommit false cursor = connection.cursor() drop_query = 'DROP DATABASE IF EXISTS "%s";' % database_name logging.info('Executing: "' + drop_query + '"') try: cursor.execute(drop_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) else: raise CommandError("Unknown database engine %s" % engine) if verbosity >= 2 or options.get("interactive"): print("Reset successful.")
def handle(self, *args, **options): """ Resets the database for this project. Note: Transaction wrappers are in reverse as a work around for autocommit, anybody know how to do this the right way? """ if args: raise CommandError("reset_db takes no arguments") router = options.get('router') dbinfo = settings.DATABASES.get(router) if dbinfo is None: raise CommandError("Unknown database router %s" % router) engine = dbinfo.get('ENGINE').split('.')[-1] user = password = database_name = database_host = database_port = '' if engine == 'mysql': (user, password, database_name, database_host, database_port) = parse_mysql_cnf(dbinfo) user = options.get('user') or dbinfo.get('USER') or user password = options.get('password') or dbinfo.get('PASSWORD') or password owner = options.get('owner') or user database_name = options.get('dbname') or dbinfo.get('NAME') or database_name if database_name == '': raise CommandError("You need to specify DATABASE_NAME in your Django settings file.") database_host = dbinfo.get('HOST') or database_host database_port = dbinfo.get('PORT') or database_port verbosity = int(options.get('verbosity', 1)) if options.get('interactive'): confirm = input(""" You have requested a database reset. This will IRREVERSIBLY DESTROY ALL data in the database "%s". Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """ % (database_name,)) else: confirm = 'yes' if confirm != 'yes': print("Reset cancelled.") return if engine in ('sqlite3', 'spatialite'): import os try: logging.info("Unlinking %s database" % engine) os.unlink(database_name) except OSError: pass elif engine in ('mysql',): import MySQLdb as Database kwargs = { 'user': user, 'passwd': password, } if database_host.startswith('/'): kwargs['unix_socket'] = database_host else: kwargs['host'] = database_host if database_port: kwargs['port'] = int(database_port) connection = Database.connect(**kwargs) drop_query = 'DROP DATABASE IF EXISTS `%s`' % database_name utf8_support = options.get('no_utf8_support', False) and '' or 'CHARACTER SET utf8' create_query = 'CREATE DATABASE `%s` %s' % (database_name, utf8_support) logging.info('Executing... "' + drop_query + '"') connection.query(drop_query) logging.info('Executing... "' + create_query + '"') connection.query(create_query) elif engine in ('postgresql', 'postgresql_psycopg2', 'postgis'): if engine == 'postgresql' and django.VERSION < (1, 9): import psycopg as Database # NOQA elif engine in ('postgresql', 'postgresql_psycopg2', 'postgis'): import psycopg2 as Database # NOQA conn_string = "dbname=template1" if user: conn_string += " user=%s" % user if password: conn_string += " password='******'" % password if database_host: conn_string += " host=%s" % database_host if database_port: conn_string += " port=%s" % database_port connection = Database.connect(conn_string) connection.set_isolation_level(0) # autocommit false cursor = connection.cursor() drop_query = "DROP DATABASE \"%s\";" % database_name logging.info('Executing... "' + drop_query + '"') try: cursor.execute(drop_query) except Database.ProgrammingError as e: logging.exception("Error: %s" % str(e)) create_query = "CREATE DATABASE \"%s\"" % database_name if owner: create_query += " WITH OWNER = \"%s\" " % owner create_query += " ENCODING = 'UTF8'" if engine == 'postgis' and django.VERSION < (1, 9): # For PostGIS 1.5, fetch template name if it exists if django.VERSION < (1, 8): from django.contrib.gis.db.backends.postgis.creation import PostGISCreation postgis_template = PostGISCreation(connection).template_postgis else: from django.contrib.gis.db.backends.postgis.base import DatabaseWrapper postgis_template = DatabaseWrapper(dbinfo).template_postgis if postgis_template is not None: create_query += ' TEMPLATE = %s' % postgis_template if settings.DEFAULT_TABLESPACE: create_query += ' TABLESPACE = %s;' % settings.DEFAULT_TABLESPACE else: create_query += ';' logging.info('Executing... "' + create_query + '"') cursor.execute(create_query) else: raise CommandError("Unknown database engine %s" % engine) if verbosity >= 2 or options.get('interactive'): print("Reset successful.")