graphql-python / graphql-python/graphene-sqlalchemy

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

Đang mở
#331 3 bình luận 0 reaction 0 người được giao Xem trên GitHub
:eyes: more info needed bug
Ngôn ngữ chính
Python
Star
985
Fork
223
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Mô tả

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
```

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Đánh giá

Issue này chưa được đánh giá.

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.