def execute(self, query, args=None): """Executes a given query with given arguments.""" # When talking to MariaDB, MySQLdb code seems to have no problem # with sending multiple statements in a single cursor.execute() # call. MySQL, on the other hand, doesn't tolerate such behavior. # It returns "Commands out of sync" error. # # It seems that according to the official spec, cursor.execute() # can accept a single statement only. See: # https://www.python.org/dev/peps/pep-0249/#id15 # ".execute(): prepare and execute a database operation # (query or command)." # # And: # https://stackoverflow.com/questions/20518677/mysqldb-cursor-execute-cant-run-multiple-queries if ";" in query: # NOTE: query doesn't contain actual data (the template substitution # is done at a later stage), so there's practically no danger of a false # positive in this check. raise SemicolonNotAllowedInQueryError( "cursor.execute() can execute a single SQL statement only") try: result = self._forward(self.cursor.execute, query, args=args) if MySQLdb.version_info >= (1, 4, 0) and self.con.warning_count(): # Newer MySQLdb versions do not automatically turn MySQL warnings into # Python warnings, so this behavior must be implemented explicitly. for warning in self.con.show_warnings(): warnings.warn(MySQLdb.Warning(*warning[1:3]), stacklevel=3) return result except Warning as e: # TODO: check if newer versions of mysqlclient report # integrity errors as MySQLdb.IntegrityError exceptions and # not simply as warnings. # # MySQL error code 1452: Cannot add or update a child row: # a foreign key constraint fails if e.args[0] == 1452: raise MySQLdb.IntegrityError(str(e)) # TODO: check if newer versions of mysqlclient report the # unknown table warning (that's thrown even if DROP TABLE IF EXISTS # syntax is used, see # https://dev.mysql.com/doc/refman/5.7/en/drop-table.html) # # MySQL error code 1051: Unknown table. if e.args[0] == 1051: return None # TODO: check if newer versions of mysqlclient still report # the CONSTRAINT...FOREIGN KEY warning as a warning and not as an # integrity error. if (isinstance(e.args[0], str) and "CONSTRAINT" in e.args[0] and "FOREIGN KEY" in e.args[0]): raise MySQLdb.IntegrityError(str(e)) raise
def executemany(self, query, args): try: return self.cursor.executemany(query, args) except Database.OperationalError, e: # Map some error codes to IntegrityError, since they seem to be # misclassified and Django would prefer the more logical place. if e[0] in self.codes_for_integrityerror: raise Database.IntegrityError(tuple(e)) raise
def __init__(self, *args, **keywds): try: Create.__init__(self, *args, **keywds) except MySQLdb.IntegrityError, error_data: self.error_message += self.MSG_INTEGRITY_ERROR % error_data[1] try: self.total_count except AttributeError: self.total_count = 0 raise MySQLdb.IntegrityError(self.error_message)
def execute(self, query, args=None): """Executes a given query with given arguments.""" # When talking to MariaDB, MySQLdb code seems to have no problem # with sending multiple statements in a single cursor.execute() # call. MySQL, on the other hand, doesn't tolerate such behavior. # It returns "Commands out of sync" error. # # It seems that according to the official spec, cursor.execute() # can accept a single statement only. See: # https://www.python.org/dev/peps/pep-0249/#id15 # ".execute(): prepare and execute a database operation # (query or command)." # # And: # https://stackoverflow.com/questions/20518677/mysqldb-cursor-execute-cant-run-multiple-queries if ";" in query: # NOTE: query doesn't contain actual data (the template substitution # is done at a later stage), so there's practically no danger of a false # positive in this check. raise SemicolonNotAllowedInQueryError( "cursor.execute() can execute a single SQL statement only") try: return self._forward(self.cursor.execute, query, args=args) except Warning as e: # TODO: check if newer versions of mysqlclient report # integrity errors as MySQLdb.IntegrityError exceptions and # not simply as warnings. # # MySQL error code 1452: Cannot add or update a child row: # a foreign key constraint fails if e.args[0] == 1452: raise MySQLdb.IntegrityError(e.message) # TODO: check if newer versions of mysqlclient report the # unknown table warning (that's thrown even if DROP TABLE IF EXISTS # syntax is used, see # https://dev.mysql.com/doc/refman/5.7/en/drop-table.html) # # MySQL error code 1051: Unknown table. if e.args[0] == 1051: return None raise
def __init__(self, *args, **keywds): try: Create.__init__(self, *args, **keywds) except MySQLdb.IntegrityError as error_data: self.error_message += self.MSG_INTEGRITY_ERROR % error_data[1] try: self.total_count except AttributeError: self.total_count = 0 raise MySQLdb.IntegrityError(self.error_message) self.id = self.cursor().insert_id() try: self.total_count += self.cursor().rowcount except AttributeError: self.total_count = self.cursor().rowcount if self.cursor().rowcount == 0: raise NoInsertionError