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)
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
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)
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)
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)
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
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
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
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
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)
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
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
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
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)
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
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)
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)
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
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