def delete_tables(self): "Deletes all model tables for our models for a clean test environment" cursor = connection.cursor() connection.disable_constraint_checking() for model in self.models: # Remove any M2M tables first for field in model._meta.local_many_to_many: with atomic(): try: cursor.execute(connection.schema_editor().sql_delete_table % { "table": connection.ops.quote_name(field.rel.through._meta.db_table), }) except DatabaseError as e: if any([s in str(e).lower() for s in self.no_table_strings]): pass else: raise # Then remove the main tables with atomic(): try: cursor.execute(connection.schema_editor().sql_delete_table % { "table": connection.ops.quote_name(model._meta.db_table), }) except DatabaseError as e: if any([s in str(e).lower() for s in self.no_table_strings]): pass else: raise connection.enable_constraint_checking()
def test_disable_constraint_checks_manually(self): """ When constraint checks are disabled, should be able to write bad data without IntegrityErrors. """ with transaction.atomic(): # Create an Article. models.Article.objects.create(headline="Test article", pub_date=datetime.datetime(2010, 9, 4), reporter=self.r) # Retrieve it from the DB a = models.Article.objects.get(headline="Test article") a.reporter_id = 30 try: connection.disable_constraint_checking() a.save() connection.enable_constraint_checking() except IntegrityError: self.fail("IntegrityError should not have occurred.") transaction.set_rollback(True)
def test_disable_constraint_checks_manually(self): """ When constraint checks are disabled, should be able to write bad data without IntegrityErrors. """ with transaction.commit_manually(): # Create an Article. models.Article.objects.create(headline="Test article", pub_date=datetime.datetime( 2010, 9, 4), reporter=self.r) # Retrive it from the DB a = models.Article.objects.get(headline="Test article") a.reporter_id = 30 try: connection.disable_constraint_checking() a.save() connection.enable_constraint_checking() except IntegrityError: self.fail("IntegrityError should not have occurred.") finally: transaction.rollback()
def delete_tables(self): "Deletes all model tables for our models for a clean test environment" with connection.cursor() as cursor: connection.disable_constraint_checking() table_names = connection.introspection.table_names(cursor) for model in self.models: # Remove any M2M tables first for field in model._meta.local_many_to_many: with atomic(): tbl = field.rel.through._meta.db_table if tbl in table_names: cursor.execute(connection.schema_editor().sql_delete_table % { "table": connection.ops.quote_name(tbl), }) try: sql = connection.ops.drop_sequence_sql(tbl) cursor.execute(sql) except Exception as e: print("Can not delete sequence for %s" % tbl) table_names.remove(tbl) # Then remove the main tables with atomic(): tbl = model._meta.db_table if tbl in table_names: cursor.execute(connection.schema_editor().sql_delete_table % { "table": connection.ops.quote_name(tbl), }) try: sql = connection.ops.drop_sequence_sql(tbl) cursor.execute(sql) except Exception as e: print("Can not delete sequence for %s" % tbl) table_names.remove(tbl) connection.enable_constraint_checking()
def delete_tables(self): "Deletes all model tables for our models for a clean test environment" cursor = connection.cursor() connection.disable_constraint_checking() table_names = connection.introspection.table_names(cursor) for model in self.models: # Remove any M2M tables first for field in model._meta.local_many_to_many: with atomic(): tbl = field.rel.through._meta.db_table if tbl in table_names: cursor.execute(connection.schema_editor().sql_delete_table % { "table": connection.ops.quote_name(tbl), }) table_names.remove(tbl) # Then remove the main tables with atomic(): tbl = model._meta.db_table if tbl in table_names: cursor.execute(connection.schema_editor().sql_delete_table % { "table": connection.ops.quote_name(tbl), }) table_names.remove(tbl) connection.enable_constraint_checking()
def set_up_test_model(self, app_label, second_model=False, third_model=False, related_model=False, mti_model=False, proxy_model=False, unique_together=False, options=False, db_table=None, index_together=False): """ Creates a test model state and database table. """ # Delete the tables if they already exist table_names = [ # Start with ManyToMany tables '_pony_stables', '_pony_vans', # Then standard model tables '_pony', '_stable', '_van', ] tables = [(app_label + table_name) for table_name in table_names] with connection.cursor() as cursor: table_names = connection.introspection.table_names(cursor) connection.disable_constraint_checking() sql_delete_table = connection.schema_editor().sql_delete_table with transaction.atomic(): for table in tables: if table in table_names: cursor.execute( sql_delete_table % {"table": connection.ops.quote_name(table)}) connection.enable_constraint_checking() # Make the "current" state model_options = { "swappable": "TEST_SWAP_MODEL", "index_together": [["weight", "pink"]] if index_together else [], "unique_together": [["pink", "weight"]] if unique_together else [], } if options: model_options["permissions"] = [("can_groom", "Can groom")] if db_table: model_options["db_table"] = db_table operations = [ migrations.CreateModel( "Pony", [ ("id", models.AutoField(primary_key=True)), ("pink", models.IntegerField(default=3)), ("weight", models.FloatField()), ], options=model_options, ) ] if second_model: operations.append( migrations.CreateModel( "Stable", [ ("id", models.AutoField(primary_key=True)), ], )) if third_model: operations.append( migrations.CreateModel( "Van", [ ("id", models.AutoField(primary_key=True)), ], )) if related_model: operations.append( migrations.CreateModel( "Rider", [ ("id", models.AutoField(primary_key=True)), ("pony", models.ForeignKey("Pony")), ("friend", models.ForeignKey("self")), ], )) if mti_model: operations.append( migrations.CreateModel( "ShetlandPony", fields=[ ('pony_ptr', models.OneToOneField( auto_created=True, primary_key=True, to_field='id', serialize=False, to='Pony', )), ("cuteness", models.IntegerField(default=1)), ], bases=['%s.Pony' % app_label], )) if proxy_model: operations.append( migrations.CreateModel( "ProxyPony", fields=[], options={"proxy": True}, bases=['%s.Pony' % app_label], )) return self.apply_operations(app_label, ProjectState(), operations)
def django_db_setup(django_db_setup, django_db_blocker): with django_db_blocker.unblock(): # Disable constraints for SQLLite connection.disable_constraint_checking()
def setUpClass(cls): connection.disable_constraint_checking() super().setUpClass()
def set_up_test_model( self, app_label, second_model=False, third_model=False, related_model=False, mti_model=False, proxy_model=False, unique_together=False, options=False, db_table=None, index_together=False): """ Creates a test model state and database table. """ # Delete the tables if they already exist table_names = [ # Start with ManyToMany tables '_pony_stables', '_pony_vans', # Then standard model tables '_pony', '_stable', '_van', ] tables = [(app_label + table_name) for table_name in table_names] with connection.cursor() as cursor: table_names = connection.introspection.table_names(cursor) connection.disable_constraint_checking() sql_delete_table = connection.schema_editor().sql_delete_table with transaction.atomic(): for table in tables: if table in table_names: cursor.execute(sql_delete_table % { "table": connection.ops.quote_name(table), }) connection.enable_constraint_checking() # Make the "current" state model_options = { "swappable": "TEST_SWAP_MODEL", "index_together": [["weight", "pink"]] if index_together else [], "unique_together": [["pink", "weight"]] if unique_together else [], } if options: model_options["permissions"] = [("can_groom", "Can groom")] if db_table: model_options["db_table"] = db_table operations = [migrations.CreateModel( "Pony", [ ("id", models.AutoField(primary_key=True)), ("pink", models.IntegerField(default=3)), ("weight", models.FloatField()), ], options=model_options, )] if second_model: operations.append(migrations.CreateModel( "Stable", [ ("id", models.AutoField(primary_key=True)), ] )) if third_model: operations.append(migrations.CreateModel( "Van", [ ("id", models.AutoField(primary_key=True)), ] )) if related_model: operations.append(migrations.CreateModel( "Rider", [ ("id", models.AutoField(primary_key=True)), ("pony", models.ForeignKey("Pony")), ("friend", models.ForeignKey("self")) ], )) if mti_model: operations.append(migrations.CreateModel( "ShetlandPony", fields=[ ('pony_ptr', models.OneToOneField( auto_created=True, primary_key=True, to_field='id', serialize=False, to='Pony', )), ("cuteness", models.IntegerField(default=1)), ], bases=['%s.Pony' % app_label], )) if proxy_model: operations.append(migrations.CreateModel( "ProxyPony", fields=[], options={"proxy": True}, bases=['%s.Pony' % app_label], )) return self.apply_operations(app_label, ProjectState(), operations)
def fix_sqlite_for_django_2(self): # We're monkey patching the __exit__ method of DatabaseSchemaEditor because it reenables constraint checking # which we explicitly DO NOT want to do. The problem is that without patching this if multiple tables have # incorrect foreign key constraints you can't fix one at a time - you have to fix both simultaneously (which # Django doesn't support). Fun times. DatabaseSchemaEditor.__exit__ = BaseDatabaseSchemaEditor.__exit__ try: constraint_check = connection.disable_constraint_checking() except: connection.connection = connection.connect() constraint_check = connection.disable_constraint_checking() # Back up the sqlite databases before we start rebuilding things, just in case. # ol2 -> ol3 try: shutil.copyfile("db.sqlite3.ol2", "db.sqlite3.ol3") except FileNotFoundError: pass # old -> ol2 try: shutil.copyfile("db.sqlite3.old", "db.sqlite3.ol2") except FileNotFoundError: pass # (db) -> old shutil.copyfile("db.sqlite3", "db.sqlite3.old") # Because Django 2.0+ now enforces FK checks for Sqlite DBs, if we are missing migrations that would now involve # FK checks we have a serious problem - We can't apply the migrations until the DB is fixed, and we can't fix # the DB until we apply the migrations. The solution is to apply the migrations with FK checks disabled, then # run this script to fix the database. I've created a management command - `migrate_no_fk` - which can handle # the migration. Let's call that now just to ensure that we're in the right state. execute_from_command_line(['manage.py', 'migrate_no_fk']) # Everything should be migrated at this point - Let's continue. # There was some kind of an issue with firmware data specifically - let's delete it all just to be safe try: self.clear_firmware_data() except: print("Unable to clear data!!") # Once that's done, we're going to attempt to loop over all the apps/models and rebuild everything just to be # safe. for app in apps.get_app_configs(): print("Rebuilding app {}...".format(app.verbose_name)) for model in app.get_models(include_auto_created=True): if model._meta.managed and not (model._meta.proxy or model._meta.swapped): for base in model.__bases__: if hasattr(base, '_meta'): base._meta.local_many_to_many = [] model._meta.local_many_to_many = [] with connection.schema_editor() as editor: try: constraint_check = connection.disable_constraint_checking( ) except: connection.connection = connection.connect() constraint_check = connection.disable_constraint_checking( ) print("Rebuilding model {}".format(model)) editor._remake_table(model) print( "Completed app rebuilding - running check_constraints to ensure we're in a consistent state." ) connection.check_constraints() config.SQLITE_OK_DJANGO_2 = True print("Rebuild complete!") return True
def setUpClass(cls): connection.disable_constraint_checking() super(TestMgmtCommands, cls).setUpClass()
def setUpClass(cls): if connection.vendor == 'sqlite': connection.disable_constraint_checking() super().setUpClass()
def tearDownClass(cls): super().tearDownClass() # Delete the schema for the test model with connection.schema_editor() as schema_editor: connection.disable_constraint_checking() schema_editor.delete_model(cls.Model)