def is_type_of(cls, root, context, info): if isinstance(root, cls): return True if not is_mapped(type(root)): raise Exception( ('Received incompatible instance "{}".').format(root)) return (isinstance(root, cls._meta.model) and type(root) != type(models.PropositionPost))
def __new__(cls, name, bases, attrs): # Also ensure initialization is only performed for subclasses of # SQLAlchemyInterface (excluding SQLAlchemyInterface class itself). if not is_base_type(bases, SQLAlchemyInterfaceMeta): return type.__new__(cls, name, bases, attrs) options = Options( attrs.pop('Meta', None), name=name, description=attrs.pop('__doc__', None), model=None, local_fields=None, only_fields=(), exclude_fields=(), # id='id', registry=None ) if not options.registry: options.registry = get_global_registry() assert isinstance(options.registry, Registry), ( 'The attribute registry in {}.Meta needs to be an' ' instance of Registry, received "{}".' ).format(name, options.registry) assert is_mapped(options.model), ( 'You need to pass a valid SQLAlchemy Model in ' '{}.Meta, received "{}".' ).format(name, options.model) cls = type.__new__(cls, name, bases, dict(attrs, _meta=options)) options.base_fields = () options.base_fields = get_base_fields(bases, _as=Field) if not options.local_fields: options.local_fields = yank_fields_from_attrs(attrs, _as=Field) # options.registry.register(cls) options.fields = merge( options.base_fields, options.local_fields ) options.sqlalchemy_fields = yank_fields_from_attrs( construct_fields(options), _as=Field, ) options.fields = merge( options.sqlalchemy_fields, options.base_fields, options.local_fields ) return cls
def __new__(cls, name, bases, attrs): # Also ensure initialization is only performed for subclasses of SQLAlchemyInterface # (excluding SQLAlchemyInterface class itself). if not is_base_type(bases, SQLAlchemyInterfaceMeta): return type.__new__(cls, name, bases, attrs) options = Options( attrs.pop('Meta', None), name=name, description=attrs.pop('__doc__', None), model=None, local_fields=None, only_fields=(), exclude_fields=(), # id='id', registry=None) if not options.registry: options.registry = get_global_registry() assert isinstance( options.registry, Registry), ('The attribute registry in {}.Meta needs to be an' ' instance of Registry, received "{}".').format( name, options.registry) assert is_mapped( options.model), ('You need to pass a valid SQLAlchemy Model in ' '{}.Meta, received "{}".').format( name, options.model) cls = type.__new__(cls, name, bases, dict(attrs, _meta=options)) options.base_fields = () options.base_fields = get_base_fields(bases, _as=Field) if not options.local_fields: options.local_fields = yank_fields_from_attrs(attrs, _as=Field) # options.registry.register(cls) options.fields = merge(options.base_fields, options.local_fields) options.sqlalchemy_fields = yank_fields_from_attrs( construct_fields(options), _as=Field, ) options.fields = merge(options.sqlalchemy_fields, options.base_fields, options.local_fields) return cls
def is_type_of(cls, root, context, info): # This is the method defined in SQLAlchemyObjectType where # we changed the isinstance by a type comparison. # For a node query, graphql in # graphene/types/typemap.py(43)resolve_type() # which calls graphql/execution/executor.py(351)get_default_resolve_type_fn() # noqa: E501 # will try to know the object type from the SA object. # It actually iterate over all registered object types and return # the first one where is_type_of return True. # And here we have in the following order Idea, Question, Thematic. # So a node query on a Thematic or Question was returning the Idea object type. # noqa: E501 # Here we fix the issue by overriding the is_type_of method # for the Idea type to do a type comparison so that # models.Question/models.Thematic which # inherits from models.Idea doesn't return true if isinstance(root, cls): return True if not is_mapped(type(root)): raise Exception( ('Received incompatible instance "{}".').format(root)) # return isinstance(root, cls._meta.model) # this was the original code # noqa: E501 return type(root) == cls._meta.model or type(root) == models.RootIdea
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