Skip to content

feat Rows result type for query execution methods #7

@Ox54

Description

@Ox54

Summary

Add a Rows result type as an alternative to returning raw lists of model instances from DB execution methods (.all(), .first(), etc.). Rows would behave like a list but provide extra conveniences for post-query manipulation. Ferro would return Rows by default, with configuration to opt out globally or per method.

Current behavior

All DB execution methods (e.g. .all(), .first()) return a list of the corresponding data models.

Proposed behavior

  • Rows – A list-like type returned by default from execution methods, with additional helpers:
    • Rows.filter(func: Callable[(X), bool]) -> Self – Filter in-memory by predicate
      • users.filter(lambda x: x.archived == false)
    • Rows.select(*fields) -> dict - Select specific fields. Returns a list if selecting a single field, dict otherwise.
      • users.select("id", "email")
    • Rows.get(field: str) -> Self – Lookup by index or key (e.g. by id)
      • users.get(email="admin@ferro.com")
    • Rows.sort(key: Callable[(X), Any], reverse: bool = False) -> Self – Sort in-memory by key/attribute
      • users.sort(key = lambda x: x.order)
    • Rows.to_pandas() -> pd.DataFrame - Convert database data to a pandas dataframe
      • users.to_pandas() # Raises exception if pandas is not installed
    • Rows.to_polars() -> pl.DataFrame - Convert database data to a polars dataframe
      • users.to_polars() # Raises exception if polars is not installed
    • (and similar conveniences as needed)

Rows should feel like a list (iterable, indexable, len(), etc.) so existing code that expects a list continues to work, while new code can use the extra methods.

Configuration

  • Global: Configure Ferro to return plain lists instead of Rows (e.g. for projects that want minimal API surface).
  • Per method: Allow opting into Rows or plain list on a per-call basis (e.g. .all(return_rows=False) or .all(return_type="list")), so callers can choose per query.

Acceptance criteria (draft)

  • Rows type is list-like (iterable, indexable, len(), sliceable).
  • Rows supports .filter, .map, .get, .sort (and any other agreed conveniences).
  • Execution methods return Rows by default.
  • Global config to default to plain list instead of Rows.
  • Per-method override to request list or Rows.
  • Documentation and tests for Rows API and configuration.

Notes

  • Naming and exact method set (filter/map/get/sort vs. others) can be refined during design.
  • Consider whether .first() returns a single model vs. a Rows of length 0 or 1 for consistency.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions