Gino: "No connection in context" error when running many-to-one relationship example

Created on 26 Jun 2019  路  3Comments  路  Source: python-gino/gino

Environment details

  • GINO version: 0.8.3
  • Python version: 3.7.3
  • asyncpg version: 0.18.3
  • aiocontextvars version: 0.2.2
  • PostgreSQL version: 10.8
  • OS: Ubuntu 18.04.1

Description

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!

All 3 comments

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!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AmatanHead picture AmatanHead  路  5Comments

myraygunbarrel picture myraygunbarrel  路  3Comments

marcojulioarg picture marcojulioarg  路  3Comments

saeedghx68 picture saeedghx68  路  6Comments

retnikt picture retnikt  路  6Comments