Implementation of MySQL SET datatype

Issue #674 resolved
Former user created an issue

I added the class MSSet (which is almost identical to MSEnum obviously) to add the MySQL SET datatype functionality. Maybe this functionality can be implemented in a future version.

http://dev.mysql.com/doc/refman/5.0/en/set.html

class MSSet(MSString):
    """MySQL SET type."""

    def __init__(self, *enums, **kw):
        """
        Construct a SET.

        Example:

          Column('myset', MSSet("'foo'", "'bar'", "'baz'"))

        Arguments are:

        enums
          The range of valid values for this SET.  Values will be used
          exactly as they appear when generating schemas

        strict
          Defaults to False: ensure that a given value is in this ENUM's
          range of permissible values when inserting or updating rows.
          Note that MySQL will not raise a fatal error if you attempt to
          store an out of range value- an alternate value will be stored
          instead.  (See MySQL SET documentation.)

        charset
          Optional, a column-level character set for this string
          value.  Takes precendence to 'ascii' or 'unicode' short-hand.

        collation
          Optional, a column-level collation for this string value.
          Takes precedence to 'binary' short-hand.

        ascii
          Defaults to False: short-hand for the ``latin1`` character set,
          generates ASCII in schema.

        unicode
          Defaults to False: short-hand for the ``ucs2`` character set,
          generates UNICODE in schema.

        binary
          Defaults to False: short-hand, pick the binary collation type
          that matches the column's character set.  Generates BINARY in
          schema.  This does not affect the type of data stored, only the
          collation of character data.
        """

        self.__ddl_values = enums

        strip_enums = [       for a in enums:
            if a[0:1](]
) == '"' or a[0:1](0:1) == "'":
                a = a[1:-1](1:-1)
            strip_enums.append(a)

        self.enums = strip_enums
        self.strict = kw.pop('strict', False)
        length = max([for v in strip_enums](len(v)))
        super(MSSet, self).__init__(length, **kw)

    def convert_bind_param(self, value, engine): 
        if self.strict and value is not None and value not in self.enums:
            raise exceptions.InvalidRequestError('"%s" not a valid value for '
                                                 'this set' % value)
        return super(MSSet, self).convert_bind_param(value, engine)

    def get_col_spec(self):
        return self._extend("SET(%s)" % ",".join(self.__ddl_values))

Comments (3)

  1. jek

    The only thing that has been holding back adding SET is the rumor that SETs were are handled poorly or inconsistently by MySQL-python and/or the version of the mysqlclient library. With unit tests added to shake out any issues with the driver, this patch can be added.

  2. Log in to comment