--- /dev/null
+"""
+psycopg3 row factories
+"""
+
+# Copyright (C) 2021 The Psycopg Team
+
+from typing import Any, Callable, Dict, Sequence
+
+from .cursor import BaseCursor
+from .proto import ConnectionType
+
+
+def dict_row(
+ cursor: BaseCursor[ConnectionType],
+) -> Callable[[Sequence[Any]], Dict[str, Any]]:
+ """Row factory to represent rows as dicts."""
+
+ def make_row(values: Sequence[Any]) -> Dict[str, Any]:
+ assert cursor.description
+ titles = (c.name for c in cursor.description)
+ return dict(zip(titles, values))
+
+ return make_row
--- /dev/null
+from psycopg3 import rows
+
+
+def test_dict_row(conn):
+ cur = conn.cursor(row_factory=rows.dict_row)
+ cur.execute("select 'bob' as name, 3 as id")
+ assert cur.fetchall() == [{"name": "bob", "id": 3}]
+
+ cur.execute("select 'a' as letter; select 1 as number")
+ assert cur.fetchall() == [{"letter": "a"}]
+ assert cur.nextset()
+ assert cur.fetchall() == [{"number": 1}]
+ assert not cur.nextset()