Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

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

Aperta
#331 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
35/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Ferma
Stack tecnologico
flask, python, sqlalchemy
Ambito
api, backend, databases

Direzione di ricerca

Inizia riproducendo il malfunzionamento con gli schema.py e app.py forniti, eseguendo Flask una volta con l’auto-reload e una volta con --no-reload. Ispeziona il percorso di batching e la gestione delle relazioni SQLAlchemy intorno a UserConvoAssociation, in particolare le relazioni back_populates e l’errore del loop degli eventi. Il lavoro è completato quando la query di introspezione ha esito positivo con il batching e l’auto-reload di Flask abilitati.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

: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
Lingua principale
Python
Stelle
985
Fork
224
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di graphql-python/graphene-sqlalchemy

Tutte le issue di graphql-python/graphene-sqlalchemy

Issue simili

Altre issue su Python

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.