graphene-django преобразует models.BigInteger() в graphene.Integer()

Я использую графен-джанго.

Я пытаюсь получить данные из поля models.BigInteger(), но когда я делаю запрос в graphiQL, я получаю сообщение об ошибке

{
  "errors": [
    {
      "message": "Int cannot represent non 32-bit signed integer value: 2554208328"
    }
  ],
  "data": {
    "match": null
  }
}

Кто-нибудь знает, как я могу заставить графен дать мне данные?


person import han juuryoku    schedule 10.08.2017    source источник


Ответы (3)


В итоге я использовал собственный скаляр. Было бы лучше, если бы это было автоматически преобразовано в лучший скаляр в graphene-django, но вот как я это исправил. Я написал файл convert.py с пользовательским скаляром BigInt, который использует число с плавающей запятой, а не целое число, если у нас есть число больше, чем MAX_INT.

# converter.py
from graphene.types import Scalar
from graphql.language import ast
from graphene.types.scalars import MIN_INT, MAX_INT

class BigInt(Scalar):
    """
    BigInt is an extension of the regular Int field
        that supports Integers bigger than a signed
        32-bit integer.
    """
    @staticmethod
    def big_to_float(value):
        num = int(value)
        if num > MAX_INT or num < MIN_INT:
            return float(int(num))
        return num

    serialize = big_to_float
    parse_value = big_to_float

    @staticmethod
    def parse_literal(node):
        if isinstance(node, ast.IntValue):
            num = int(node.value)
            if num > MAX_INT or num < MIN_INT:
                return float(int(num))
            return num

потом

# schema.py
from .converter import BigInt
class MatchType(DjangoObjectType):
    game_id = graphene.Field(BigInt)
    class Meta:
        model = Match
        interfaces = (graphene.Node, )
        filter_fields = {}
person import han juuryoku    schedule 11.08.2017

Вы можете зарегистрировать новый конвертер:

    import graphene
    from graphene_django.converter import convert_django_field

    @convert_django_field.register(models.BigIntegerField)
    def convert_bigint_to_float(field, registry=None):
        return graphene.Float(description=field.help_text, required=not field.null)

Именно так он используется в самом graphene-django.

person bulatsh    schedule 05.08.2018

Это из исходного кода графена (но, я думаю, еще не выпущен): ="nofollow noreferrer">https://github.com/graphql-python/graphene/blob/485b1ed325287fd721b13aac8b4ec872d6295c6a/graphene/types/scalars.py#L85

class BigInt(Scalar):
"""
The `BigInt` scalar type represents non-fractional whole numeric values.
`BigInt` is not constrained to 32-bit like the `Int` type and thus is a less
compatible type.
"""

@staticmethod
def coerce_int(value):
    try:
        num = int(value)
    except ValueError:
        try:
            num = int(float(value))
        except ValueError:
            return None
    return num

serialize = coerce_int
parse_value = coerce_int

@staticmethod
def parse_literal(ast):
    if isinstance(ast, IntValueNode):
        return int(ast.value)

Я думаю, что код в другом ответе может быть на самом деле лучше, но хотел связать это на всякий случай.

person Craig Wallace    schedule 29.06.2021