I am having trouble replicating the example provided in the docs here: https://python-gino.readthedocs.io/en/latest/loaders.html#many-to-one-relationship
Here is the script I am running:
import asyncio
from gino import Gino
CONN_STRING = ...
db = Gino()
class Parent(db.Model):
__tablename__ = 'parents'
id = db.Column(db.Integer, primary_key=True)
class Child(db.Model):
__tablename__ = 'children'
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey('parents.id'))
async def main():
await db.set_bind(CONN_STRING)
await db.gino.create_all()
await Parent.create(id=1)
await Parent.create(id=2)
await Parent.create(id=3)
await Child.create(id=1, parent_id=1)
await Child.create(id=2, parent_id=1)
await Child.create(id=3, parent_id=2)
await Child.create(id=4, parent_id=3)
await Child.create(id=5, parent_id=3)
# everything runs fine till it reaches this part
async for child in Child.load(parent=Parent).query.gino.iterate():
print(f'Parent of {child.id} is {child.parent.id}')
await db.pop_bind().close()
if __name__ == '__main__':
asyncio.get_event_loop().run_until_complete(main())
This is the error and a partial stack trace:
ValueError: No Connection in context, please provide one
File "main.py", line 56, in main
async for child in Child.load(parent=Parent).query.gino.iterate():
File ".../lib/python3.7/site-packages/gino/api.py", line 171, in iterate
'No Connection in context, please provide one')
Thanks!
So I tried opening a transaction and it worked:
I replaced:
async for child in Child.load(parent=Parent).query.gino.iterate():
print(f'Parent of {child.id} is {child.parent.id}')
with
async with db.transaction():
async for child in Child.load(parent=Parent).query.gino.iterate():
print(f'Parent of {child.id} is {child.parent.id}')
Follow-up question:
Is a transaction always needed for loading?
Oh, iterate() internally calls cursor() of asyncpg, which requires a transaction.
Thanks for clarifying that!