Пример #1
0
  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
Пример #2
0
 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
Пример #3
0
    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)
Пример #4
0
  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
Пример #5
0
    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