Example #1
0
    def to_db_types_sql_asts(self) -> List[AST]:
        asts = []

        existing_enums = {}
        with self.transaction():
            rv = self.execute(
                'select t.typname, e.enumlabel from pg_type as t join pg_enum as e on t.oid = e.enumtypid'
            )
            for name, label in rv:
                existing_enums.setdefault(name, []).append(label)

        seen = set()

        for model in self._models:
            for k in model.__sorted_fields__:
                f = getattr(model, k)

                if isinstance(f.type, type) and issubclass(f.type, Enum):
                    enum_name = camel2underscore(f.type.__name__)

                    if enum_name in seen:
                        continue

                    seen.add(enum_name)

                    enum_labels = existing_enums.get(enum_name)

                    if enum_labels is None:
                        enum_labels = list(f.type.__members__)
                        asts.append([
                            'CREATE_ENUM',
                            enum_name,
                            enum_labels,
                        ])
                        continue

                    for member_name in f.type.__members__:
                        if member_name not in enum_labels:
                            asts.append([
                                'ADD_ENUM_LABEL', enum_name,
                                enum_labels[-1] if enum_labels else '',
                                member_name
                            ])
                            enum_labels.append(member_name)
        return asts
Example #2
0
    def post_FIELD_TYPE(self, type_, length, auto_increment):
        # pylint: disable=too-many-statements
        if type_ in (int, long):
            if auto_increment:
                f_type = 'SERIAL'
            elif length is not None:
                if length < 2:
                    f_type = 'TINYINT'  # pragma: no cover
                elif length < 8:
                    f_type = 'SMALLINT'
                else:
                    f_type = 'INT'
            else:
                f_type = 'BIGINT'
        elif type_ in (str, unicode):
            if length is not None:
                f_type = 'VARCHAR({})'.format(length)
            else:
                f_type = 'TEXT'  # pragma: no cover
        elif type_ is float:
            f_type = 'FLOAT'  # pragma: no cover
        elif type_ is Decimal:
            f_type = 'DECIMAL'  # pragma: no cover
        elif type_ is date:
            f_type = 'DATE'
        elif type_ is datetime:
            f_type = 'TIMESTAMP'
        elif type_ is bytes:
            f_type = 'BYTEA'
        elif isinstance(type_, type) and issubclass(type_, Enum):
            f_type = camel2underscore(type_.__name__)
        elif type_ is bool:
            f_type = 'BOOLEAN'
        elif type_ is JSONLike:
            f_type = 'JSONB'
        else:
            f_type = 'TEXT'

        return f_type, []
Example #3
0
    def __init__(cls, class_name, bases, attrs):
        super(ModelMeta, cls).__init__(class_name, bases, attrs)

        (
            fields,
            db_fields,
            primary_key,
            on_updates,
            choices_field_sets,
            validates,
            exported_property_names,
            ordered_field_attr_names,
            field_name_map,
            encrypted_fields,
        ) = _collect_fields(cls, attrs)

        cls.__fields__ = fields
        cls.__db_fields__ = db_fields
        cls.__all_fields__ = fields | db_fields
        cls.__choices_field_sets__ = choices_field_sets
        cls.__validates__ = validates
        cls.__exported_property_names__ = exported_property_names
        cls.__ordered_field_attr_names__ = ordered_field_attr_names
        cls.__field_name_map__ = field_name_map
        cls.__encrypted_fields__ = encrypted_fields

        if '__table_name__' not in attrs:
            cls.__table_name__ = camel2underscore(class_name)

        if hasattr(cls, '__on_updates__'):
            _on_updates = cls.__on_updates__.copy()
            _on_updates.update(on_updates)
            cls.__on_updates__ = _on_updates
        else:
            cls.__on_updates__ = on_updates

        if not hasattr(cls, '__primary_key__') or not cls.__primary_key__:
            cls.__primary_key__ = primary_key

        uk = getattr(cls, '__unique_key__', None)
        uks = getattr(cls, '__unique_keys__', None) or set()

        uks = set(uks)

        # compat __unique_key__
        if uk:
            uks.add(uk)  # pragma: no cover
            del cls.__unique_key__  # pragma: no cover

        cls.__unique_keys__ = set(
            filter(lambda x: x is not None,
                   (_process_key(cls, uk) for uk in uks)))
        cls.__primary_key__ = _process_key(cls, cls.__primary_key__)

        index_keys = set()
        order_bys = set()

        for base in bases:
            index_keys |= getattr(base, '__index_keys__', set())
            order_bys |= getattr(base, '__order_bys__', set())

        _, uks, iks = _get_keys_from_db(cls)

        cls.__unique_keys__ |= set(uks)

        # index keys
        _index_keys = set(
            filter(lambda x: x is not None,
                   (_process_key(cls, k)
                    for k in attrs.get('__index_keys__', [])))) | set(iks)

        cls.__index_keys__ = index_keys

        for key in _index_keys:
            cls.__index_keys__.update(set(_product_index_keys(key)))

        # order bys
        _order_bys = {(k, ) if not isinstance(k, tuple) else k
                      for k in attrs.get('__order_bys__', [])}

        cls.__order_bys__ = order_bys | _order_bys | (set(
            _product_order_by_tuples(cls.__primary_key__)))

        cls._lock = threading.RLock()

        old_init = attrs.get('__init__')

        if old_init and getattr(old_init, '_override', False):

            @wraps(old_init)
            def wrapped_init(self, *args, **kwargs):
                with model_instantiate_context(self.__ctx__):
                    return old_init(self, *args, **kwargs)

            cls.__init__ = wrapped_init
            cls._olo_is_breaked = True

        cls.__ctx__ = Context()