Hacktoberfest 2026 : les issues que les mainteneurs ont marquées pour octobre, ouvertes et accessibles aux débutants. Parcourir les issues Hacktoberfest

[Bug] Batching throws error when Flask auto-reload is enabled

Ouverte
#331 3 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
35/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
À l'abandon
Stack technique
flask, python, sqlalchemy
Domaine
api, backend, databases

Piste de recherche

Commencez par reproduire l’échec avec les fichiers schema.py et app.py fournis, en exécutant Flask une fois avec l’auto-reload et une fois avec --no-reload. Examinez le chemin de batching et la gestion des relations SQLAlchemy autour de UserConvoAssociation, en particulier les relations back_populates et l’erreur de boucle d’événements. Le travail est considéré comme terminé lorsque la requête d’introspection réussit avec le batching et l’auto-reload de Flask activés.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

:eyes: more info needed bug

Hi,

I'm currently upgrading a graphene 2 project to graphene 3. The project uses graphene-sqlalchemy and graphql-server[flask]. I'm noticing strange behavior when using batching while flask is in development mode, specifically when auto-reload is enabled. When auto-reload is enabled and batching is enabled, then all requests fail. Instead an asyncio error is thrown, TypeError: UserConvo fields cannot be resolved. There is no current event loop in thread 'Thread-1'. The issue only occurs when batching is enabled and flask auto reload is enabled. Disabling batching or disabling the flask auto-reload resolves the issue. The issue also only occurs with a many to many relationship that include the back_populates param in the relationships.

Below is a [somewhat] minimal example to reproduce the issue. The app.py, schema.py, and requirements.txt file are below.

Let me know if you need more info or clarification. Thanks!

Repro:
0) set up a virtual env and install packages from requirements.txt below. Then copy app.py and schema.py to your working directory.

  1. run: FLASK_ENV=development && flask run
  2. execute query { __schema { types { name } } } and receive error TypeError: UserConvo fields cannot be resolved. There is no current event loop in thread 'Thread-1'.
  3. run `FLASK_ENV=development && flask run --no-reload
  4. execute query { __schema { types { name } } } and receive no error.

Error Trace:

Traceback (most recent call last):
  File "/Users/erichemphill/workspace/craft/graphene-test/app.py", line 4, in <module>
    from schema import schema
  File "/Users/erichemphill/workspace/craft/graphene-test/schema.py", line 74, in <module>
    schema = Schema(query=Query)
  File "/Users/erichemphill/workspace/craft/graphene-test/env/lib/python3.8/site-packages/graphene/types/schema.py", line 430, in __init__
    self.graphql_schema = GraphQLSchema(
  File "/Users/erichemphill/workspace/craft/graphene-test/env/lib/python3.8/site-packages/graphql/type/schema.py", line 208, in __init__
    collect_referenced_types(query)
  File "/Users/erichemphill/workspace/craft/graphene-test/env/lib/python3.8/site-packages/graphql/type/schema.py", line 423, in collect_referenced_types
    collect_referenced_types(field.type)
  File "/Users/erichemphill/workspace/craft/graphene-test/env/lib/python3.8/site-packages/graphql/type/schema.py", line 422, in collect_referenced_types
    for field in named_type.fields.values():
  File "/opt/homebrew/Cellar/python@3.8/3.8.12_1/Frameworks/Python.framework/Versions/3.8/lib/python3.8/functools.py", line 967, in __get__
    val = self.func(instance)
  File "/Users/erichemphill/workspace/craft/graphene-test/env/lib/python3.8/site-packages/graphql/type/definition.py", line 737, in fields
    raise TypeError(f"{self.name} fields cannot be resolved. {error}")
TypeError: UserConvo fields cannot be resolved. There is no current event loop in thread 'Thread-1'.

schema.py:

from graphene import Field, ObjectType, Schema
from graphene import relay
from graphene_sqlalchemy import SQLAlchemyObjectType
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Column, Integer, ForeignKey, BigInteger

Base = declarative_base()

class UserModel(Base):  # pylint: disable=too-few-public-methods
    """
    Models the User Object
    """

    __tablename__ = "user"
    user_id = Column(BigInteger, primary_key=True, autoincrement=True)
    convos = relationship("UserConvoAssociation", back_populates="user")

class UserConvoAssociation(Base):
    """
    Association Object for User and Convo relationships
    """

    __tablename__ = "user_convo"
    convo_id = Column(ForeignKey("convo.convo_id"), primary_key=True)
    user_id = Column(ForeignKey("user.user_id"), primary_key=True)
    num_unread_messages = Column(Integer, default=0)

    convo = relationship("ConvoModel", back_populates="users")
    user = relationship("UserModel", back_populates="convos")
    
class ConvoModel(Base):  # pylint: disable=too-few-public-methods
    """
    Models the Convo object
    """

    __tablename__ = "convo"
    convo_id = Column(BigInteger, primary_key=True, autoincrement=True)
    users = relationship("UserConvoAssociation", back_populates="convo")


class UserConvo(SQLAlchemyObjectType):
    """
    User x Convo relationship
    """

    class Meta:
        model = UserConvoAssociation
        interfaces = (relay.Node,)
        batching = True


class User(SQLAlchemyObjectType):
    """
    Defines the schema for a User
    """

    class Meta:
        """
        Defines the metadata for a User
        """

        model = UserModel
        interfaces = (relay.Node,)
        batching = True


class Query(ObjectType):
    convo = Field(UserConvo)
    user = Field(User)

schema = Schema(query=Query)

app.py

from flask import Flask
from graphql_server.flask import GraphQLView

from schema import schema

app = Flask(__name__)

app.add_url_rule('/graphql', view_func=GraphQLView.as_view(
    'graphql',
    schema=schema.graphql_schema,
    graphiql=True,
))

if __name__ == '__main__':
    app.run()

requirements.txt (this is not a minimal requirements.txt. it's from the project that i'm working on.)

aiodataloader==0.2.1
aiohttp==4.0.0a1
alembic==1.7.6
aniso8601==9.0.1
asgiref==3.5.0
async-timeout==3.0.1
attrs==21.4.0
aws-embedded-metrics==1.0.7
bcrypt==3.2.0
boto3==1.21.1
botocore==1.24.1
certifi==2021.10.8
cffi==1.15.0
cfn-flip==1.3.0
chardet==3.0.4
charset-normalizer==2.0.12
click==8.0.3
exponent-server-sdk==2.0.0
Flask==2.0.3
Flask-Migrate==3.1.0
Flask-SQLAlchemy==2.5.1
graphene==3.0
graphene-sqlalchemy==3.0.0b1
graphql-core==3.1.7
graphql-relay==3.1.5
graphql-server==3.0.0b4
idna==3.3
importlib-metadata==4.11.1
importlib-resources==5.4.0
itsdangerous==2.0.1
Jinja2==3.0.3
jmespath==0.10.0
Mako==1.1.6
MarkupSafe==2.0.1
multidict==4.7.6
phonenumbers==8.12.43
promise==2.3
psycopg2==2.9.3
pycparser==2.21
python-dateutil==2.8.2
python-http-client==3.3.6
PyYAML==5.3.1
requests==2.27.1
s3transfer==0.5.1
sendgrid==6.9.6
six==1.16.0
SQLAlchemy==1.4.31
starkbank-ecdsa==2.0.3
troposphere==3.2.2
typing-extensions==3.10.0.2
urllib3==1.26.8
Werkzeug==2.0.3
yarl==1.7.2
zipp==3.7.0
Langage dominant
Python
Étoiles
985
Forks
224
Métriques de merge des PR
Aucune PR mergée en 30 j

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de graphql-python/graphene-sqlalchemy

Toutes les issues de graphql-python/graphene-sqlalchemy

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.