tursodatabase/turso · error · KeyError
KeyError(key)
Error message
KeyError(key)
What it means
Row.__getitem__ resolves string keys through an index built from the result set's column names; integer and slice keys go straight to the underlying data tuple. A string that is not one of the selected column names raises KeyError(key). The row only knows the names the SELECT actually returned, not the full table schema.
Source
Thrown at bindings/python/turso/lib.py:1168
obj._data = data
# Build mapping from column name to index
desc = cursor.description or ()
obj._keys = tuple(col[0] for col in desc)
obj._index = {name: idx for idx, name in enumerate(obj._keys)}
return obj
def keys(self) -> list[str]:
return list(self._keys)
def __getitem__(self, key: int | str | slice, /) -> Any:
if isinstance(key, slice):
return self._data[key]
if isinstance(key, int):
return self._data[key]
# key is column name
idx = self._index.get(key)
if idx is None:
raise KeyError(key)
return self._data[idx]
def __hash__(self) -> int:
return hash((self._keys, self._data))
def __iter__(self) -> Iterator[Any]:
return iter(self._data)
def __len__(self) -> int:
return len(self._data)
def __eq__(self, value: object, /) -> bool:
if not isinstance(value, Row):
return NotImplemented # type: ignore[return-value]
return self._keys == value._keys and self._data == value._data
def __ne__(self, value: object, /) -> bool:
if not isinstance(value, Row):View on GitHub (pinned to c1e5928725)
Solutions
- Print row.keys() once and use the exact names the query returned
- Alias computed columns in the SELECT list (SELECT count(*) AS n FROM t)
- Select explicit columns instead of * so the name set is stable
- Access by integer index when names are unstable
Example fix
# before
cur.execute("SELECT count(*) FROM t")
row = cur.fetchone()
row["total"] # KeyError('total')
# after
cur.execute("SELECT count(*) AS total FROM t")
row = cur.fetchone()
row["total"] # works Defensive patterns
Strategy: validation
Validate before calling
def column_or(row, name, default=None):
return row[name] if name in row.keys() else default Type guard
def has_column(row, name: str) -> bool:
return name in row.keys() Try / catch
try:
value = row["total"]
except KeyError:
value = row[row.keys()[0]] # or log row.keys() and fix the SELECT Prevention
- Log row.keys() once after execute when wiring up new queries
- Alias every expression column in the SELECT list
- Select explicit columns instead of * when code reads by name
When it happens
Trigger: row['typo'] after a normal query; a name that differs from the SELECT list, such as an unaliased aggregate or expression column; a column dropped or renamed by a schema migration while the code still selects *.
Common situations: SELECT * across a migration that renames a column; joins returning one bare name for two same-named columns; trusting keys from external JSON instead of row.keys(); case mismatches with the query text.
Related errors
- pyturso's SQLAlchemy dialects require SQLAlchemy >= 2.0.45 (
- Cannot get raw connection from SQLAlchemy connection
- Expected turso.sync.ConnectionSync, got {type(dbapi_conn).__
- Unsupported value type: {type(value).__name__}
- invalid value in server response: {e}
AI-assisted analysis of tursodatabase/turso@c1e5928725 (2026-08-20).
Data as JSON: /api/errors/265e4595cd7000e8.
Report an issue: GitHub.