From 125c625fbc46244a4b4025732e1526fb13c55843 Mon Sep 17 00:00:00 2001 From: Simon Willison Date: Wed, 15 Apr 2020 20:12:55 -0700 Subject: [PATCH] .rows_where(..., order_by=) argument, closes #76 --- docs/python-api.rst | 18 +++++++++++++++++- sqlite_utils/db.py | 4 +++- tests/test_rows.py | 22 ++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/docs/python-api.rst b/docs/python-api.rst index 310fb01..51f05fb 100644 --- a/docs/python-api.rst +++ b/docs/python-api.rst @@ -92,7 +92,7 @@ View objects are similar to Table objects, except that any attempts to insert or * ``count`` * ``schema`` * ``rows`` -* ``rows_where(where, where_args)`` +* ``rows_where(where, where_args, order_by)`` * ``drop()`` .. _python_api_rows: @@ -115,6 +115,22 @@ You can filter rows by a WHERE clause using ``.rows_where(where, where_args)``:: ... print(row) {'id': 1, 'age': 4, 'name': 'Cleo'} +To specify an order, use the ``order_my=`` argument:: + + >>> for row in db["dogs"].rows_where("age > 1", order_by="age"): + ... print(row) + {'id': 2, 'age': 2, 'name': 'Pancakes'} + {'id': 1, 'age': 4, 'name': 'Cleo'} + +You can use ``order_by="age desc"`` for descending order. + +You can order all records in the table by excluding the ``where`` argument:: + + >>> for row in db["dogs"].rows_where(order_by="age desc"): + ... print(row) + {'id': 1, 'age': 4, 'name': 'Cleo'} + {'id': 2, 'age': 2, 'name': 'Pancakes'} + .. _python_api_get: Retrieving a specific record diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index 3f9bb6f..d92e92e 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -437,12 +437,14 @@ class Queryable: def rows(self): return self.rows_where() - def rows_where(self, where=None, where_args=None): + def rows_where(self, where=None, where_args=None, order_by=None): if not self.exists(): return [] sql = "select * from [{}]".format(self.name) if where is not None: sql += " where " + where + if order_by is not None: + sql += " order by " + order_by cursor = self.db.conn.execute(sql, where_args or []) columns = [c[0] for c in cursor.description] for row in cursor: diff --git a/tests/test_rows.py b/tests/test_rows.py index 115f26a..539d71d 100644 --- a/tests/test_rows.py +++ b/tests/test_rows.py @@ -27,3 +27,25 @@ def test_rows_where(where, where_args, expected_ids, fresh_db): pk="id", ) assert expected_ids == {r["id"] for r in table.rows_where(where, where_args)} + + +@pytest.mark.parametrize( + "where,order_by,expected_ids", + [ + (None, None, [1, 2, 3]), + (None, "id desc", [3, 2, 1]), + (None, "age", [3, 2, 1]), + ("id > 1", "age", [3, 2]), + ], +) +def test_rows_where_order_by(where, order_by, expected_ids, fresh_db): + table = fresh_db["dogs"] + table.insert_all( + [ + {"id": 1, "name": "Cleo", "age": 4}, + {"id": 2, "name": "Pancakes", "age": 3}, + {"id": 3, "name": "Bailey", "age": 2}, + ], + pk="id", + ) + assert expected_ids == [r["id"] for r in table.rows_where(where, order_by=order_by)]