Skip to content

Commit

Permalink
Refactor _process_results to support new DB engines (#1054)
Browse files Browse the repository at this point in the history
  • Loading branch information
dantownsend authored Jul 21, 2024
1 parent e7b13fb commit 4ed6938
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 19 deletions.
6 changes: 3 additions & 3 deletions piccolo/columns/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,11 @@ def get_default_alias(self):

if self.call_chain:
column_name = (
"$".join(
".".join(
t.cast(str, i._meta.db_column_name)
for i in self.call_chain
)
+ f"${column_name}"
+ f".{column_name}"
)

return column_name
Expand Down Expand Up @@ -291,7 +291,7 @@ def get_full_name(
'band$manager.name'
>>> Band.manager.name._meta.get_full_name(with_alias=True)
'band$manager.name AS "manager$name"'
'band$manager.name AS "manager.name"'
:param include_quotes:
If you're using the name in a SQL query, each component needs to be
Expand Down
7 changes: 7 additions & 0 deletions piccolo/engine/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,13 @@ async def run_querystring(
):
pass

def transform_response_to_dicts(self, results) -> t.List[t.Dict]:
"""
If the database adapter returns something other than a list of
dictionaries, it should perform the transformation here.
"""
return results

@abstractmethod
async def run_ddl(self, ddl: str, in_pool: bool = True):
pass
Expand Down
7 changes: 7 additions & 0 deletions piccolo/engine/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,13 @@ async def run_ddl(self, ddl: str, in_pool: bool = True):

return response

def transform_response_to_dicts(self, results) -> t.List[t.Dict]:
"""
asyncpg returns a special Record object, so we need to convert it to
a dict.
"""
return [dict(i) for i in results]

def atomic(self) -> Atomic:
return Atomic(engine=self)

Expand Down
19 changes: 5 additions & 14 deletions piccolo/query/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,11 @@ def engine_type(self) -> str:
raise ValueError("Engine isn't defined.")

async def _process_results(self, results) -> QueryResponseType:
if results:
keys = results[0].keys()
keys = [i.replace("$", ".") for i in keys]
if self.engine_type in ("postgres", "cockroach"):
# asyncpg returns a special Record object. We can pass it
# directly into zip without calling `values` on it. This can
# save us hundreds of microseconds, depending on the number of
# results.
raw = [dict(zip(keys, i)) for i in results]
else:
# SQLite returns a list of dictionaries.
raw = [dict(zip(keys, i.values())) for i in results]
else:
raw = []
raw = (
self.table._meta.db.transform_response_to_dicts(results)
if results
else []
)

if hasattr(self, "_raw_response_callback"):
self._raw_response_callback(raw)
Expand Down
2 changes: 1 addition & 1 deletion piccolo/query/methods/select.py
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,7 @@ def default_querystrings(self) -> t.Sequence[QueryString]:
query += "{}"
args.append(distinct.querystring)

columns_str = ", ".join("{}" for i in select_strings)
columns_str = ", ".join("{}" for _ in select_strings)
query += f" {columns_str} FROM {self.table._meta.get_formatted_tablename()}" # noqa: E501
args.extend(select_strings)

Expand Down
2 changes: 1 addition & 1 deletion piccolo/querystring.py
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ def get_select_string(
self, engine_type: str, with_alias: bool = True
) -> QueryString:
if with_alias and self._alias:
return QueryString("{} AS " + self._alias, self)
return QueryString("{} AS " + f'"{self._alias}"', self)
else:
return self

Expand Down

0 comments on commit 4ed6938

Please sign in to comment.