Skip to content

Commit a5345e0

Browse files
committed
feat: add orders & limit parameter to select_custom_fields
1 parent d2caf58 commit a5345e0

File tree

4 files changed

+46
-13
lines changed

4 files changed

+46
-13
lines changed

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class AccountMgr(BaseManager, metaclass=DemoMetaclass):
2828

2929
## Some supported efficient sql
3030
### **select_custom_fields**
31-
**without `groupbys`**
31+
**basic example**
3232
```python
3333
await AccountMgr.select_custom_fields(
3434
fields=[
@@ -47,14 +47,16 @@ Generate sql and execute
4747
WHERE id IN (1, 2, 3)
4848
```
4949

50-
**with `groupbys`**
50+
**complex example**
5151
```python
5252
await AccountMgr.select_custom_fields(
5353
fields=[
5454
"locale", "gender", "COUNT(1) cnt"
5555
],
5656
wheres=["id BETWEEN 1 AND 12"],
57-
groupbys=["locale", "gender"],
57+
groups=["locale", "gender"],
58+
orders=["locale", "-gender"],
59+
limit=10,
5860
)
5961
```
6062
Generate sql and execute
@@ -64,6 +66,8 @@ Generate sql and execute
6466
FROM account
6567
WHERE id BETWEEN 1 AND 12
6668
GROUP BY locale, gender
69+
ORDER BY locale ASC, gender DESC
70+
LIMIT 10
6771
```
6872

6973
### **upsert_json_field**

examples/service/routers/account.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,9 @@ async def query_group_by_locale_view(
5656
"locale", "gender", "COUNT(1) cnt"
5757
],
5858
wheres=["id BETWEEN 1 AND 12"],
59-
groupbys=["locale", "gender"],
59+
groups=["locale", "gender"],
60+
orders=["locale", "-gender"],
61+
limit=10,
6062
)
6163
return {"dicts": dicts}
6264

fastapi_esql/orm/base_manager.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,18 @@ async def select_custom_fields(
6464
cls,
6565
fields: List[str],
6666
wheres: List[str],
67-
groupbys: Optional[List[str]] = None,
67+
groups: Optional[List[str]] = None,
68+
orders: Optional[List[str]] = None,
69+
limit: int = 0,
6870
conn: Optional[BaseDBAsyncClient] = None,
6971
):
7072
sql = SQLizer.select_custom_fields(
7173
cls.table,
7274
fields,
7375
wheres,
74-
groupbys,
76+
groups,
77+
orders,
78+
limit,
7579
)
7680
conn = conn or cls.ro_conn
7781
return await CursorHandler.fetch_dicts(sql, conn, logger)

fastapi_esql/utils/sqlizer.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,17 @@ def __init__(self, sql: str):
1818

1919
class SQLizer:
2020

21+
@classmethod
22+
def resolve_ordering(cls, orderings: List[str]) -> str:
23+
orders = []
24+
for o in orderings:
25+
if o.startswith("-"):
26+
order = "DESC"
27+
else:
28+
order = "ASC"
29+
orders.append(f"{o.strip('-')} {order}")
30+
return ", ".join(orders)
31+
2132
@classmethod
2233
def _sqlize_value(cls, value, to_json=False) -> str:
2334
"""
@@ -45,18 +56,30 @@ def select_custom_fields(
4556
table: str,
4657
fields: List[str],
4758
wheres: List[str],
48-
groupbys: Optional[List[str]] = None,
59+
groups: Optional[List[str]] = None,
60+
orders: Optional[List[str]] = None,
61+
limit: int = 0,
4962
) -> Optional[str]:
5063
if not all([table, fields, wheres]):
5164
raise WrongParamsError("Please check your params")
5265

53-
group_by = f"GROUP BY {', '.join(groupbys)}" if groupbys else ""
54-
sql = f"""
66+
group_by = f" GROUP BY {', '.join(groups)}" if groups else ""
67+
order_by = f" ORDER BY {cls.resolve_ordering(orders)}" if orders else ""
68+
limit_ = f" LIMIT {limit}" if limit else ""
69+
# NOTE Doesn't support `offset` parameter due to it's bad performance
70+
extras = [group_by, order_by, limit_]
71+
72+
sql = """
5573
SELECT
56-
{", ".join(fields)}
57-
FROM {table}
58-
WHERE {" AND ".join(wheres)}
59-
{group_by}"""
74+
{}
75+
FROM {}
76+
WHERE {}
77+
{}""".format(
78+
", ".join(fields),
79+
table,
80+
" AND ".join(wheres),
81+
"\n".join(extras) if extras else "",
82+
)
6083
logger.debug(sql)
6184
return sql
6285

0 commit comments

Comments
 (0)