def report_unexpected_exception(self, out, test, example, exc_info): doctest.DocTestRunner.report_unexpected_exception(self, out, test, example, exc_info) # Rollback, in case of database errors. Otherwise they'd have # side effects on other tests. for conn in connections: transaction.rollback_unless_managed(using=conn)
def _rollback_on_exception(**kwargs): from djangocg.db import transaction for conn in connections: try: transaction.rollback_unless_managed(using=conn) except DatabaseError: pass
def _reset_sequences(self, db_name): conn = connections[db_name] if conn.features.supports_sequence_reset: sql_list = \ conn.ops.sequence_reset_by_name_sql(no_style(), conn.introspection.sequence_list()) if sql_list: try: cursor = conn.cursor() for sql in sql_list: cursor.execute(sql) except Exception: transaction.rollback_unless_managed(using=db_name) raise transaction.commit_unless_managed(using=db_name)
def handle_label(self, tablename, **options): db = options.get('database') cache = BaseDatabaseCache(tablename, {}) if not router.allow_syncdb(db, cache.cache_model_class): return connection = connections[db] fields = ( # "key" is a reserved word in MySQL, so use "cache_key" instead. models.CharField(name='cache_key', max_length=255, unique=True, primary_key=True), models.TextField(name='value'), models.DateTimeField(name='expires', db_index=True), ) table_output = [] index_output = [] qn = connection.ops.quote_name for f in fields: field_output = [qn(f.name), f.db_type(connection=connection)] field_output.append("%sNULL" % (not f.null and "NOT " or "")) if f.primary_key: field_output.append("PRIMARY KEY") elif f.unique: field_output.append("UNIQUE") if f.db_index: unique = f.unique and "UNIQUE " or "" index_output.append("CREATE %sINDEX %s ON %s (%s);" % \ (unique, qn('%s_%s' % (tablename, f.name)), qn(tablename), qn(f.name))) table_output.append(" ".join(field_output)) full_statement = ["CREATE TABLE %s (" % qn(tablename)] for i, line in enumerate(table_output): full_statement.append(' %s%s' % (line, i < len(table_output)-1 and ',' or '')) full_statement.append(');') curs = connection.cursor() try: curs.execute("\n".join(full_statement)) except DatabaseError as e: transaction.rollback_unless_managed(using=db) raise CommandError( "Cache table '%s' could not be created.\nThe error was: %s." % (tablename, force_text(e))) for statement in index_output: curs.execute(statement) transaction.commit_unless_managed(using=db)
def _base_set(self, mode, key, value, timeout=None): if timeout is None: timeout = self.default_timeout db = router.db_for_write(self.cache_model_class) table = connections[db].ops.quote_name(self._table) cursor = connections[db].cursor() cursor.execute("SELECT COUNT(*) FROM %s" % table) num = cursor.fetchone()[0] now = timezone.now() now = now.replace(microsecond=0) if settings.USE_TZ: exp = datetime.utcfromtimestamp(time.time() + timeout) else: exp = datetime.fromtimestamp(time.time() + timeout) exp = exp.replace(microsecond=0) if num > self._max_entries: self._cull(db, cursor, now) pickled = pickle.dumps(value, pickle.HIGHEST_PROTOCOL) encoded = base64.b64encode(pickled).strip() cursor.execute("SELECT cache_key, expires FROM %s " "WHERE cache_key = %%s" % table, [key]) try: result = cursor.fetchone() if result and (mode == 'set' or (mode == 'add' and result[1] < now)): cursor.execute("UPDATE %s SET value = %%s, expires = %%s " "WHERE cache_key = %%s" % table, [encoded, connections[db].ops.value_to_db_datetime(exp), key]) else: cursor.execute("INSERT INTO %s (cache_key, value, expires) " "VALUES (%%s, %%s, %%s)" % table, [key, encoded, connections[db].ops.value_to_db_datetime(exp)]) except DatabaseError: # To be threadsafe, updates/inserts are allowed to fail silently transaction.rollback_unless_managed(using=db) return False else: transaction.commit_unless_managed(using=db) return True
def handle_noargs(self, **options): verbosity = int(options.get("verbosity")) interactive = options.get("interactive") show_traceback = options.get("traceback") load_initial_data = options.get("load_initial_data") self.style = no_style() # Import the 'management' module within each installed app, to register # dispatcher events. for app_name in settings.INSTALLED_APPS: try: import_module(".management", app_name) except ImportError as exc: # This is slightly hackish. We want to ignore ImportErrors # if the "management" module itself is missing -- but we don't # want to ignore the exception if the management module exists # but raises an ImportError for some reason. The only way we # can do this is to check the text of the exception. Note that # we're a bit broad in how we check the text, because different # Python implementations may not use the same text. # CPython uses the text "No module named management" # PyPy uses "No module named myproject.myapp.management" msg = exc.args[0] if not msg.startswith("No module named") or "management" not in msg: raise db = options.get("database") connection = connections[db] cursor = connection.cursor() # Get a list of already installed *models* so that references work right. tables = connection.introspection.table_names() seen_models = connection.introspection.installed_models(tables) created_models = set() pending_references = {} # Build the manifest of apps and models that are to be synchronized all_models = [ ( app.__name__.split(".")[-2], [m for m in models.get_models(app, include_auto_created=True) if router.allow_syncdb(db, m)], ) for app in models.get_apps() ] def model_installed(model): opts = model._meta converter = connection.introspection.table_name_converter return not ( (converter(opts.db_table) in tables) or (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables) ) manifest = SortedDict( (app_name, list(filter(model_installed, model_list))) for app_name, model_list in all_models ) # Create the tables for each model if verbosity >= 1: self.stdout.write("Creating tables ...\n") for app_name, model_list in manifest.items(): for model in model_list: # Create the model's database table, if it doesn't already exist. if verbosity >= 3: self.stdout.write("Processing %s.%s model\n" % (app_name, model._meta.object_name)) sql, references = connection.creation.sql_create_model(model, self.style, seen_models) seen_models.add(model) created_models.add(model) for refto, refs in references.items(): pending_references.setdefault(refto, []).extend(refs) if refto in seen_models: sql.extend( connection.creation.sql_for_pending_references(refto, self.style, pending_references) ) sql.extend(connection.creation.sql_for_pending_references(model, self.style, pending_references)) if verbosity >= 1 and sql: self.stdout.write("Creating table %s\n" % model._meta.db_table) for statement in sql: cursor.execute(statement) tables.append(connection.introspection.table_name_converter(model._meta.db_table)) transaction.commit_unless_managed(using=db) # Send the post_syncdb signal, so individual apps can do whatever they need # to do at this point. emit_post_sync_signal(created_models, verbosity, interactive, db) # The connection may have been closed by a syncdb handler. cursor = connection.cursor() # Install custom SQL for the app (but only if this # is a model we've just created) if verbosity >= 1: self.stdout.write("Installing custom SQL ...\n") for app_name, model_list in manifest.items(): for model in model_list: if model in created_models: custom_sql = custom_sql_for_model(model, self.style, connection) if custom_sql: if verbosity >= 2: self.stdout.write( "Installing custom SQL for %s.%s model\n" % (app_name, model._meta.object_name) ) try: for sql in custom_sql: cursor.execute(sql) except Exception as e: self.stderr.write( "Failed to install custom SQL for %s.%s model: %s\n" % (app_name, model._meta.object_name, e) ) if show_traceback: traceback.print_exc() transaction.rollback_unless_managed(using=db) else: transaction.commit_unless_managed(using=db) else: if verbosity >= 3: self.stdout.write("No custom SQL for %s.%s model\n" % (app_name, model._meta.object_name)) if verbosity >= 1: self.stdout.write("Installing indexes ...\n") # Install SQL indices for all newly created models for app_name, model_list in manifest.items(): for model in model_list: if model in created_models: index_sql = connection.creation.sql_indexes_for_model(model, self.style) if index_sql: if verbosity >= 2: self.stdout.write( "Installing index for %s.%s model\n" % (app_name, model._meta.object_name) ) try: for sql in index_sql: cursor.execute(sql) except Exception as e: self.stderr.write( "Failed to install index for %s.%s model: %s\n" % (app_name, model._meta.object_name, e) ) transaction.rollback_unless_managed(using=db) else: transaction.commit_unless_managed(using=db) # Load initial_data fixtures (unless that has been disabled) if load_initial_data: call_command("loaddata", "initial_data", verbosity=verbosity, database=db, skip_validation=True)
def handle_noargs(self, **options): db = options.get('database') connection = connections[db] verbosity = int(options.get('verbosity')) interactive = options.get('interactive') # 'reset_sequences' is a stealth option reset_sequences = options.get('reset_sequences', True) self.style = no_style() # Import the 'management' module within each installed app, to register # dispatcher events. for app_name in settings.INSTALLED_APPS: try: import_module('.management', app_name) except ImportError: pass sql_list = sql_flush(self.style, connection, only_django=True, reset_sequences=reset_sequences) if interactive: confirm = input("""You have requested a flush of the database. This will IRREVERSIBLY DESTROY all data currently in the %r database, and return each table to the state it was in after syncdb. Are you sure you want to do this? Type 'yes' to continue, or 'no' to cancel: """ % connection.settings_dict['NAME']) else: confirm = 'yes' if confirm == 'yes': try: cursor = connection.cursor() for sql in sql_list: cursor.execute(sql) except Exception as e: transaction.rollback_unless_managed(using=db) raise CommandError("""Database %s couldn't be flushed. Possible reasons: * The database isn't running or isn't configured correctly. * At least one of the expected database tables doesn't exist. * The SQL was invalid. Hint: Look at the output of 'django-admin.py sqlflush'. That's the SQL this command wasn't able to run. The full error: %s""" % (connection.settings_dict['NAME'], e)) transaction.commit_unless_managed(using=db) # Emit the post sync signal. This allows individual # applications to respond as if the database had been # sync'd from scratch. all_models = [] for app in models.get_apps(): all_models.extend([ m for m in models.get_models(app, include_auto_created=True) if router.allow_syncdb(db, m) ]) emit_post_sync_signal(set(all_models), verbosity, interactive, db) # Reinstall the initial_data fixture. kwargs = options.copy() kwargs['database'] = db if options.get('load_initial_data'): # Reinstall the initial_data fixture. call_command('loaddata', 'initial_data', **options) else: self.stdout.write("Flush cancelled.\n")
def _save(feat_range=default_range, num_feat=0, num_saved=0): if feat_range: layer_iter = self.layer[feat_range] else: layer_iter = self.layer for feat in layer_iter: num_feat += 1 # Getting the keyword arguments try: kwargs = self.feature_kwargs(feat) except LayerMapError as msg: # Something borked the validation if strict: raise elif not silent: stream.write('Ignoring Feature ID %s because: %s\n' % (feat.fid, msg)) else: # Constructing the model using the keyword args is_update = False if self.unique: # If we want unique models on a particular field, handle the # geometry appropriately. try: # Getting the keyword arguments and retrieving # the unique model. u_kwargs = self.unique_kwargs(kwargs) m = self.model.objects.using(self.using).get(**u_kwargs) is_update = True # Getting the geometry (in OGR form), creating # one from the kwargs WKT, adding in additional # geometries, and update the attribute with the # just-updated geometry WKT. geom = getattr(m, self.geom_field).ogr new = OGRGeometry(kwargs[self.geom_field]) for g in new: geom.add(g) setattr(m, self.geom_field, geom.wkt) except ObjectDoesNotExist: # No unique model exists yet, create. m = self.model(**kwargs) else: m = self.model(**kwargs) try: # Attempting to save. m.save(using=self.using) num_saved += 1 if verbose: stream.write('%s: %s\n' % (is_update and 'Updated' or 'Saved', m)) except SystemExit: raise except Exception as msg: if self.transaction_mode == 'autocommit': # Rolling back the transaction so that other model saves # will work. transaction.rollback_unless_managed() if strict: # Bailing out if the `strict` keyword is set. if not silent: stream.write('Failed to save the feature (id: %s) into the model with the keyword arguments:\n' % feat.fid) stream.write('%s\n' % kwargs) raise elif not silent: stream.write('Failed to save %s:\n %s\nContinuing\n' % (kwargs, msg)) # Printing progress information, if requested. if progress and num_feat % progress_interval == 0: stream.write('Processed %d features, saved %d ...\n' % (num_feat, num_saved)) # Only used for status output purposes -- incremental saving uses the # values returned here. return num_saved, num_feat