Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Conversation

pvanliefland
Copy link
Contributor

As of now, fetch_val does not work for raw queries in Postgres. Possibly related to the discussion in #101.

This is a simple fix that will distinguish between row[0] and row['foo'] in the case of raw queries.

await database.fetch_val("SELECT foo FROM bar")

in core.py:

async def fetch_val(
    self,
    query: typing.Union[ClauseElement, str],
    values: dict = None,
    column: typing.Any = 0,
) -> typing.Any:
    async with self._query_lock:
        row = await self._connection.fetch_one(self._build_query(query, values))
    return None if row is None else row[column]

in backends/postgres.py:

def __getitem__(self, key: typing.Any) -> typing.Any:
    if len(self._column_map) == 0:  # raw query
        return self._row[tuple(self._row.keys()).index(key)]

In this case, key is 0, while tuple(self.row.keys()) is ('id',), which raises ValueError: tuple.index(x): x not in tuple

@gvbgduh
Copy link
Contributor

gvbgduh commented Jul 25, 2019

@pvanliefland asyncpg actually has fetchval method, in contradiction to mysql and sqlite, so instead of
return self._row[key if type(key) is int else tuple(self._row.keys()).index(key)]
it's possible to implement it
in postgres.py

    async def fetch_val(self, query: ClauseElement) -> typing.Optional[typing.Mapping]:
        assert self._connection is not None, "Connection is not acquired"
        query, args, result_columns = self._compile(query)
        row = await self._connection.fetchval(query, *args)
        if row is None:
            return None
        return row

and in core.py

    async def fetch_val(
        self,
        query: typing.Union[ClauseElement, str],
        values: dict = None,
        column: typing.Any = 0,
    ) -> typing.Any:
        async with self._query_lock:
            row = await self._connection.fetch_val(self._build_query(query, values))
        return row

it also requires implementation of fetch_val in other backends in a way it's implemented in core.py now.
A bit more work, but it gets rid of this overhead for postgres as asyncpg just returns the value.

@pvanliefland
Copy link
Contributor Author

@gvbgduh good idea, will do :)

@gvbgduh
Copy link
Contributor

gvbgduh commented Jul 25, 2019

awesome!

@blueyed
Copy link
Contributor

blueyed commented Sep 10, 2019

For reference: #132

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants