Esempio n. 1
0
    def __init_subclass_with_meta__(cls,
                                    model=None,
                                    registry=None,
                                    only_fields=(),
                                    exclude_fields=None,
                                    **options):
        meta = SQLAlchemyMutationOptions(cls)
        meta.model = model

        model_inspect = sqlalchemyinspect(model)
        for column in model_inspect.columns:
            column.nullable = True

        cls._model_inspect = model_inspect

        if not isinstance(exclude_fields, list):
            if exclude_fields:
                exclude_fields = list(exclude_fields)
            else:
                exclude_fields = []

        for relationship in model_inspect.relationships:
            exclude_fields.append(relationship.key)

        if not registry:
            registry = get_global_registry()

        arguments = yank_fields_from_attrs(construct_fields(
            model, registry, only_fields, exclude_fields),
                                           _as=Argument)

        super(SQLAlchemyListDelete,
              cls).__init_subclass_with_meta__(_meta=meta,
                                               arguments=arguments,
                                               **options)
Esempio n. 2
0
def construct_fields(options):
    exclude_fields = set(options.exclude_fields)
    inspected_model = sqlalchemyinspect(options.model)

    fields = OrderedDict()

    for name, column in inspected_model.columns.items():
        info = getattr(column, 'info', None)
        if isinstance(info, BitMask):
            if info.has(HiddenField):
                exclude_fields.add(name)
            info = getattr(info, '_info', None)

        if _is_graphql(info):
            if hasattr(
                    info,
                    '_meta') and not getattr(info._meta, 'description', None):
                setattr(info._meta, 'description', get_column_doc(column))
            info = Field(info,
                         description=get_column_doc(column),
                         required=not (is_column_nullable(column)))
            fields[name] = info
            exclude_fields.add(name)

    for name, column in inspected_model.columns.items():
        if name in exclude_fields or name in options.fields:
            continue
        converted_type, converted_args = convert_sqlalchemy_column(
            column, options.registry)
        converted_column = converted_type(**converted_args)
        fields[name] = converted_column

    return fields
Esempio n. 3
0
    def construct_fields(cls):
        only_fields = cls._meta.only_fields
        exclude_fields = cls._meta.exclude_fields
        already_created_fields = {f.attname for f in cls._meta.local_fields}
        inspected_model = sqlalchemyinspect(cls._meta.model)

        # Get all the columns for the relationships on the model
        for relationship in inspected_model.relationships:
            is_not_in_only = only_fields and relationship.key not in only_fields
            is_already_created = relationship.key in already_created_fields
            is_excluded = relationship.key in exclude_fields or is_already_created
            if is_not_in_only or is_excluded:
                # We skip this field if we specify only_fields and is not
                # in there. Or when we excldue this field in exclude_fields
                continue
            converted_relationship = convert_sqlalchemy_relationship(
                relationship)
            cls.add_to_class(relationship.key, converted_relationship)

        for name, column in inspected_model.columns.items():
            is_not_in_only = only_fields and name not in only_fields
            is_already_created = name in already_created_fields
            is_excluded = name in exclude_fields or is_already_created
            if is_not_in_only or is_excluded:
                # We skip this field if we specify only_fields and is not
                # in there. Or when we excldue this field in exclude_fields
                continue
            converted_column = convert_sqlalchemy_column(column)
            cls.add_to_class(name, converted_column)
Esempio n. 4
0
    def __init_subclass_with_meta__(cls,
                                    model=None,
                                    registry=None,
                                    only_fields=(),
                                    exclude_fields=None,
                                    **options):
        meta = SQLAlchemyMutationOptions(cls)
        meta.model = model

        model_inspect = sqlalchemyinspect(model)
        cls._model_inspect = model_inspect

        only_fields = []
        exclude_fields = ()
        for primary_key_column in model_inspect.primary_key:
            only_fields.append(primary_key_column.name)

        if not registry:
            registry = get_global_registry()

        arguments = yank_fields_from_attrs(construct_fields(
            model, registry, only_fields, exclude_fields),
                                           _as=Argument)

        super(SQLAlchemyDelete,
              cls).__init_subclass_with_meta__(_meta=meta,
                                               arguments=arguments,
                                               **options)
Esempio n. 5
0
    def construct_fields(cls):
        only_fields = cls._meta.only_fields
        exclude_fields = cls._meta.exclude_fields
        already_created_fields = {f.attname for f in cls._meta.local_fields}
        inspected_model = sqlalchemyinspect(cls._meta.model)

        # Get all the columns for the relationships on the model
        for relationship in inspected_model.relationships:
            is_not_in_only = only_fields and relationship.key not in only_fields
            is_already_created = relationship.key in already_created_fields
            is_excluded = relationship.key in exclude_fields or is_already_created
            if is_not_in_only or is_excluded:
                # We skip this field if we specify only_fields and is not
                # in there. Or when we excldue this field in exclude_fields
                continue
            converted_relationship = convert_sqlalchemy_relationship(relationship)
            cls.add_to_class(relationship.key, converted_relationship)

        for name, column in inspected_model.columns.items():
            is_not_in_only = only_fields and name not in only_fields
            is_already_created = name in already_created_fields
            is_excluded = name in exclude_fields or is_already_created
            if is_not_in_only or is_excluded:
                # We skip this field if we specify only_fields and is not
                # in there. Or when we excldue this field in exclude_fields
                continue
            converted_column = convert_sqlalchemy_column(column)
            cls.add_to_class(name, converted_column)
Esempio n. 6
0
def construct_fields(model, registry, only_fields, exclude_fields):
    inspected_model = sqlalchemyinspect(model)

    fields = OrderedDict()

    for name, column in inspected_model.columns.items():
        is_not_in_only = only_fields and name not in only_fields
        # is_already_created = name in options.fields
        is_excluded = name in exclude_fields  # or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we exclude this field in exclude_fields
            continue
        converted_column = convert_sqlalchemy_column(column, registry)
        fields[name] = converted_column

    for name, composite in inspected_model.composites.items():
        is_not_in_only = only_fields and name not in only_fields
        # is_already_created = name in options.fields
        is_excluded = name in exclude_fields  # or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we exclude this field in exclude_fields
            continue
        converted_composite = convert_sqlalchemy_composite(composite, registry)
        fields[name] = converted_composite

    for hybrid_item in inspected_model.all_orm_descriptors:

        if type(hybrid_item) == hybrid_property:
            name = hybrid_item.__name__

            is_not_in_only = only_fields and name not in only_fields
            # is_already_created = name in options.fields
            is_excluded = name in exclude_fields  # or is_already_created

            if is_not_in_only or is_excluded:
                # We skip this field if we specify only_fields and is not
                # in there. Or when we exclude this field in exclude_fields
                continue

            converted_hybrid_property = convert_sqlalchemy_hybrid_method(
                hybrid_item
            )
            fields[name] = converted_hybrid_property

    # Get all the columns for the relationships on the model
    for relationship in inspected_model.relationships:
        is_not_in_only = only_fields and relationship.key not in only_fields
        # is_already_created = relationship.key in options.fields
        is_excluded = relationship.key in exclude_fields  # or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we exclude this field in exclude_fields
            continue
        converted_relationship = convert_sqlalchemy_relationship(relationship, registry)
        name = relationship.key
        fields[name] = converted_relationship

    return fields
Esempio n. 7
0
def construct_fields(options):
    exclude_fields = set(options.exclude_fields)
    inspected_model = sqlalchemyinspect(options.model)

    fields = OrderedDict()

    for name, column in inspected_model.columns.items():
        info = getattr(column, 'info', None)
        if isinstance(info, BitMask):
            if info.has(HiddenField):
                exclude_fields.add(name)
            else:
                info = info._info

        if _is_graphql(info):
            if hasattr(info, '_meta') and not getattr(info._meta, 'description', None):
                setattr(info._meta, 'description', get_column_doc(column))
            info = Field(info, description=get_column_doc(column), required=not(is_column_nullable(column)))
            fields[name] = info
            exclude_fields.add(name)

    for name, column in inspected_model.columns.items():
        if name in exclude_fields or name in options.fields:
            continue
        converted_column = convert_sqlalchemy_column(column, options.registry)
        fields[name] = converted_column

    return fields
Esempio n. 8
0
 def build_columns_dict(of_type):
     columns_dict = {}
     inspected_model = sqlalchemyinspect(of_type._meta.model)
     for column in inspected_model.columns:
         column.nullable = True  # Set nullable to false to build an optional graph type
         graphene_type = convert_sqlalchemy_column(column)
         columns_dict[column.name] = graphene_type
     return columns_dict
Esempio n. 9
0
def mask_field(dao, bit_mask, inspect=True):
    inspected_model = sqlalchemyinspect(dao) if inspect else dao

    ret = {}
    for name, column in inspected_model.columns.items():
        info = getattr(column, 'info', None)
        if isinstance(info, BitMask):
            if info.has(bit_mask):
                ret[name] = column
    return ret
Esempio n. 10
0
    def __init_subclass_with_meta__(cls,
                                    model=None,
                                    registry=None,
                                    optional_fields=[],
                                    only_fields=(),
                                    exclude_fields=None,
                                    **options):
        meta = SQLAlchemyMutationOptions(cls)
        meta.model = model

        model_inspect = sqlalchemyinspect(model)
        cls._model_inspect = model_inspect

        if not isinstance(exclude_fields, list):
            if exclude_fields:
                exclude_fields = list(exclude_fields)
            else:
                exclude_fields = []

        for primary_key_column in model_inspect.primary_key:
            if primary_key_column.autoincrement:
                exclude_fields.append(primary_key_column.name)

        for relationship in model_inspect.relationships:
            exclude_fields.append(relationship.key)

        for field in model_inspect.all_orm_descriptors:
            if type(field) == hybrid_property:
                exclude_fields.append(field.__name__)

        if not registry:
            registry = get_global_registry()

        fields = construct_fields(model, registry, only_fields, exclude_fields)

        for field_name in optional_fields:
            if field_name in fields:
                fields[field_name].kwargs["required"] = False

        argument_cls = getattr(cls, "Arguments", None)
        if argument_cls:
            fields.update(props(argument_cls))

        arguments = yank_fields_from_attrs(fields, _as=Argument)

        super(SQLAlchemyMutation,
              cls).__init_subclass_with_meta__(_meta=meta,
                                               arguments=arguments,
                                               **options)
Esempio n. 11
0
def construct_fields_for_input(obj_type, model, registry,
                               connection_field_factory, only_fields,
                               exclude_fields):
    inspected_model = sqlalchemyinspect(model)

    fields = OrderedDict()

    for name, column in inspected_model.columns.items():
        is_not_in_only = only_fields and name not in only_fields
        # is_already_created = name in options.fields
        is_excluded = name in exclude_fields  # or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we exclude this field in exclude_fields
            continue
        converted_column = convert_sqlalchemy_column(column, registry)
        fields[name] = converted_column

    for name, composite in inspected_model.composites.items():
        is_not_in_only = only_fields and name not in only_fields
        # is_already_created = name in options.fields
        is_excluded = name in exclude_fields  # or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we exclude this field in exclude_fields
            continue
        converted_composite = convert_sqlalchemy_composite(composite, registry)
        fields[name] = converted_composite

    for hybrid_item in inspected_model.all_orm_descriptors:

        if type(hybrid_item) == hybrid_property:
            name = hybrid_item.__name__
            is_not_in_only = only_fields and name not in only_fields
            # is_already_created = name in options.fields
            is_excluded = name in exclude_fields  # or is_already_created
            if is_not_in_only or is_excluded:
                # We skip this field if we specify only_fields and is not
                # in there. Or when we exclude this field in exclude_fields
                continue
            converted_hybrid_property = convert_sqlalchemy_hybrid_method(
                hybrid_item)

            fields[name] = converted_hybrid_property

    return fields
Esempio n. 12
0
def construct_fields(options):
    only_fields = options.only_fields
    exclude_fields = options.exclude_fields
    inspected_model = sqlalchemyinspect(options.model)

    fields = OrderedDict()

    for name, column in inspected_model.columns.items():
        is_not_in_only = only_fields and name not in only_fields
        is_already_created = name in options.fields
        is_excluded = name in exclude_fields or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we excldue this field in exclude_fields
            continue
        converted_column = convert_sqlalchemy_column(column, options.registry)
        fields[name] = converted_column

    for name, composite in inspected_model.composites.items():
        is_not_in_only = only_fields and name not in only_fields
        is_already_created = name in options.fields
        is_excluded = name in exclude_fields or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we excldue this field in exclude_fields
            continue
        converted_composite = convert_sqlalchemy_composite(
            composite, options.registry)
        fields[name] = converted_composite

    # Get all the columns for the relationships on the model
    for relationship in inspected_model.relationships:
        is_not_in_only = only_fields and relationship.key not in only_fields
        is_already_created = relationship.key in options.fields
        is_excluded = relationship.key in exclude_fields or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we excldue this field in exclude_fields
            continue
        converted_relationship = convert_sqlalchemy_relationship(
            relationship, options.registry)
        name = relationship.key
        fields[name] = converted_relationship

    return fields
Esempio n. 13
0
def construct_fields(options):
    only_fields = options.only_fields
    exclude_fields = options.exclude_fields
    inspected_model = sqlalchemyinspect(options.model)

    fields = OrderedDict()

    for name, column in inspected_model.columns.items():
        is_not_in_only = only_fields and name not in only_fields
        is_already_created = name in options.fields
        is_excluded = name in exclude_fields or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we excldue this field in exclude_fields
            continue
        converted_column = convert_sqlalchemy_column(column, options.registry)
        fields[name] = converted_column

    for name, composite in inspected_model.composites.items():
        is_not_in_only = only_fields and name not in only_fields
        is_already_created = name in options.fields
        is_excluded = name in exclude_fields or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we excldue this field in exclude_fields
            continue
        converted_composite = convert_sqlalchemy_composite(composite, options.registry)
        fields[name] = converted_composite

    # Get all the columns for the relationships on the model
    for relationship in inspected_model.relationships:
        is_not_in_only = only_fields and relationship.key not in only_fields
        is_already_created = relationship.key in options.fields
        is_excluded = relationship.key in exclude_fields or is_already_created
        if is_not_in_only or is_excluded:
            # We skip this field if we specify only_fields and is not
            # in there. Or when we excldue this field in exclude_fields
            continue
        converted_relationship = convert_sqlalchemy_relationship(relationship, options.registry)
        name = relationship.key
        fields[name] = converted_relationship

    return fields
Esempio n. 14
0
    def __init_subclass_with_meta__(cls,
                                    model=None,
                                    registry=None,
                                    only_fields=(),
                                    exclude_fields=None,
                                    **options):
        meta = SQLAlchemyMutationOptions(cls)
        meta.model = model

        model_inspect = sqlalchemyinspect(model)
        cls._model_inspect = model_inspect

        if not isinstance(exclude_fields, list):
            if exclude_fields:
                exclude_fields = list(exclude_fields)
            else:
                exclude_fields = []

        for primary_key_column in model_inspect.primary_key:
            if primary_key_column.autoincrement:
                exclude_fields.append(primary_key_column.name)

        for relationship in model_inspect.relationships:
            exclude_fields.append(relationship.key)

        if not registry:
            registry = get_global_registry()

        arguments = yank_fields_from_attrs(
            construct_fields(model, registry, only_fields, exclude_fields),
            _as=Argument,
        )

        super(SQLAlchemyCreate,
              cls).__init_subclass_with_meta__(_meta=meta,
                                               arguments=arguments,
                                               **options)
Esempio n. 15
0
    def __new__(cls, name, bases, attrs):

        if not is_base_type(bases, SQLAlchemyMutationMeta):
            return type.__new__(cls, name, bases, attrs)

        input_class = attrs.pop('Meta', None)

        if not input_class or not getattr(input_class, 'model', None) or \
                not getattr(input_class, 'field', None):
            return MutationMeta.__new__(cls, name, bases, attrs)

        assert is_mapped(input_class.model), ('You need valid SQLAlchemy Model in {}.Meta, received "{}".').format(name, input_class.model)

        field_name = camel_to_snake(input_class.model.__name__)
        inspected_model = sqlalchemyinspect(input_class.model)

        def mutate(cls, instance, args, context, info):
            session = cls.query
            arg_attrs = {}
            primary_key = {}
            for name, column in inspected_model.columns.items():
                if column.primary_key and name in args:
                    try:
                        klazz, pk = base64.b64decode(args['id']).split(b":")
                    except:
                        pk = args.get(name, None)
                    finally:
                        primary_key[name] = int(pk)
                    continue
                if name in args:
                    arg_attrs[name] = args.get(name, None)

            if len(primary_key) > 0:
                 session.query(input_class.model).filter_by(**primary_key).update(arg_attrs)
                 session.commit()
                 field = session.query(input_class.model).filter_by(**primary_key).first()
            else:
                field = input_class.model(**arg_attrs)
                session.add(field)

            try:
                session.commit()
                ok = True
                message = "ok"
            except SQLAlchemyError as e:
                session.rollback()
                message = e.message
                ok = False

            kwargs = {
                'ok': ok,
                'message': message,
                field_name: field
            }
            return cls(**kwargs)

        input_attrs = {}

        for name, column in inspected_model.columns.items():
            input_attrs[name] = convert_sqlalchemy_column(column)
            if column.default or column.server_default or column.primary_key:
                input_attrs[name].kwargs['required'] = False

        mutation_attrs = {
            'Input': type('Input', (object,), input_attrs),
            'ok': graphene.Boolean(),
            'message': graphene.String(),
            'mutate': classmethod(mutate),
            field_name: graphene.Field(input_class.field)
        }

        cls = MutationMeta.__new__(cls, name, bases, mutation_attrs)
        return cls
Esempio n. 16
0
 def _build_dao(self, options, tables):
     for _table in tables:
         table = sqlalchemyinspect(_table)
         file_name = options.classname(table) + options.file_ext
         self.render(options, file_name, table = table)
Esempio n. 17
0
 def _build_model_(self, options, tables):
     for _table in tables:
         table = sqlalchemyinspect(_table)
         file_name = options.classname(table) + '_' + options.file_ext
         self.render(options, file_name, table = table)
Esempio n. 18
0
def construct_fields(obj_type, model, registry, only_fields, exclude_fields,
                     connection_field_factory):
    """
    Construct all the fields for a SQLAlchemyObjectType.
    The main steps are:
      - Gather all the relevant attributes from the SQLAlchemy model
      - Gather all the ORM fields defined on the type
      - Merge in overrides and build up all the fields

    :param SQLAlchemyObjectType obj_type:
    :param model: the SQLAlchemy model
    :param Registry registry:
    :param tuple[string] only_fields:
    :param tuple[string] exclude_fields:
    :param function connection_field_factory:
    :rtype: OrderedDict[str, graphene.Field]
    """
    inspected_model = sqlalchemyinspect(model)
    # Gather all the relevant attributes from the SQLAlchemy model in order
    all_model_attrs = OrderedDict(
        inspected_model.column_attrs.items() +
        inspected_model.composites.items() +
        [(name, item)
         for name, item in inspected_model.all_orm_descriptors.items()
         if isinstance(item, hybrid_property)] +
        inspected_model.relationships.items())

    # Filter out excluded fields
    auto_orm_field_names = []
    for attr_name, attr in all_model_attrs.items():
        if (only_fields
                and attr_name not in only_fields) or (attr_name
                                                      in exclude_fields):
            continue
        auto_orm_field_names.append(attr_name)

    # Gather all the ORM fields defined on the type
    custom_orm_fields_items = [(attn_name, attr)
                               for base in reversed(obj_type.__mro__)
                               for attn_name, attr in base.__dict__.items()
                               if isinstance(attr, ORMField)]
    custom_orm_fields_items = sorted(custom_orm_fields_items,
                                     key=lambda item: item[1])

    # Set the model_attr if not set
    for orm_field_name, orm_field in custom_orm_fields_items:
        attr_name = orm_field.kwargs.get('model_attr', orm_field_name)
        if attr_name not in all_model_attrs:
            raise ValueError(("Cannot map ORMField to a model attribute.\n"
                              "Field: '{}.{}'").format(
                                  obj_type.__name__,
                                  orm_field_name,
                              ))
        orm_field.kwargs['model_attr'] = attr_name

    # Merge automatic fields with custom ORM fields
    orm_fields = OrderedDict(custom_orm_fields_items)
    for orm_field_name in auto_orm_field_names:
        if orm_field_name in orm_fields:
            continue
        orm_fields[orm_field_name] = ORMField(model_attr=orm_field_name)

    # Build all the field dictionary
    fields = OrderedDict()
    for orm_field_name, orm_field in orm_fields.items():
        attr_name = orm_field.kwargs.pop('model_attr')
        attr = all_model_attrs[attr_name]

        if isinstance(attr, ColumnProperty):
            field = convert_sqlalchemy_column(attr, registry,
                                              **orm_field.kwargs)
        elif isinstance(attr, RelationshipProperty):
            field = convert_sqlalchemy_relationship(attr, registry,
                                                    connection_field_factory,
                                                    **orm_field.kwargs)
        elif isinstance(attr, CompositeProperty):
            if attr_name != orm_field_name or orm_field.kwargs:
                # TODO Add a way to override composite property fields
                raise ValueError(
                    "ORMField kwargs for composite fields must be empty. "
                    "Field: {}.{}".format(obj_type.__name__, orm_field_name))
            field = convert_sqlalchemy_composite(attr, registry)
        elif isinstance(attr, hybrid_property):
            field = convert_sqlalchemy_hybrid_method(attr, attr_name,
                                                     **orm_field.kwargs)
        else:
            raise Exception(
                'Property type is not supported')  # Should never happen

        registry.register_orm_field(obj_type, orm_field_name, attr)
        fields[orm_field_name] = field

    return fields
Esempio n. 19
0
 def tryGetTableByType(self, val, tables):
     tmap = {name_from_repr(i) : i for i in tables}
     tname = val.name
     table = tmap.get(tname, None)
     return sqlalchemyinspect(table) if table else None