graphql-python / graphql-python/graphene-sqlalchemy

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

Abierto
#331 3 comentarios 0 reacciones 0 asignados Ver en GitHub
:eyes: more info needed bug
Lenguaje dominante
Python
Estrellas
985
Forks
223
Métricas de merge de PR
Sin PR fusionados en 30 d

Descripción

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
from schema import schema
File "/Users/erichemphill/workspace/craft/graphene-test/schema.py", line 74, in
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
```

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.