Skip to content

Commit f36bac7

Browse files
authored
feat: add Cases (#1)
* feat: add Cases * style
1 parent ff5abde commit f36bac7

File tree

6 files changed

+44
-19
lines changed

6 files changed

+44
-19
lines changed

README.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ Generate sql and execute
107107
WHERE `id`=8
108108
```
109109

110-
### **upsert_on_duplicated**
110+
### **upsert_on_duplicate**
111111
```python
112-
await AccountMgr.upsert_on_duplicated(
112+
await AccountMgr.upsert_on_duplicate(
113113
[
114114
{'id': 7, 'gender': 1, 'name': '斉藤 修平', 'locale': 'ja_JP', 'extend': {}},
115115
{'id': 8, 'gender': 1, 'name': 'Ojas Salvi', 'locale': 'en_IN', 'extend': {}},
@@ -133,8 +133,9 @@ Generate sql and execute
133133
```python
134134
await AccountMgr.insert_into_select(
135135
wheres=Q(id__in=[4, 5, 6]),
136-
remain_fields=["gender", "locale"],
136+
remain_fields=["gender"],
137137
assign_field_dict={
138+
"locale": Cases("id", {3: LocaleEnum.zh_CN, 4: LocaleEnum.en_US, 5: LocaleEnum.fr_FR}, default=""),
138139
"active": False,
139140
"name": RawSQL("CONCAT(LEFT(name, 26), ' [NEW]')"),
140141
"extend": {},
@@ -146,14 +147,14 @@ Generate sql and execute
146147
```sql
147148
INSERT INTO account_bak
148149
(gender, locale, active, name, extend)
149-
SELECT gender, locale, False active, CONCAT(LEFT(name, 26), ' [NEW]') name, '{}' extend
150+
SELECT gender, CASE id WHEN 3 THEN 'zh_CN' WHEN 4 THEN 'en_US' WHEN 5 THEN 'fr_FR' ELSE '' END locale, False active, CONCAT(LEFT(name, 26), ' [NEW]') name, '{}' extend
150151
FROM account
151152
WHERE `id` IN (4,5,6)
152153
```
153154

154-
### **bulk_update_with_fly_table**
155+
### **bulk_update**
155156
```python
156-
await AccountMgr.bulk_update_with_fly_table(
157+
await AccountMgr.bulk_update(
157158
[
158159
{'id': 7, 'active': False, 'gender': <GenderEnum.male: 1>},
159160
{'id': 15, 'active': True, 'gender': <GenderEnum.unknown: 0>}

examples/service/routers/account.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from faker import Faker
55
from fastapi import APIRouter, Body, Query
6-
from fastapi_esql import RawSQL
6+
from fastapi_esql import Cases, RawSQL
77
from pydantic import BaseModel, Field
88
from tortoise.queryset import Q
99

@@ -149,7 +149,7 @@ async def bulk_upsert_view():
149149
"locale": locale.value,
150150
"extend": {},
151151
})
152-
row_cnt = await AccountMgr.upsert_on_duplicated(
152+
row_cnt = await AccountMgr.upsert_on_duplicate(
153153
dicts,
154154
insert_fields=["id", "gender", "name", "locale", "extend"],
155155
upsert_fields=["name", "locale"],
@@ -164,8 +164,9 @@ async def bulk_clone_view(
164164
):
165165
ok = await AccountMgr.insert_into_select(
166166
wheres=Q(id__in=aids),
167-
remain_fields=["gender", "locale"],
167+
remain_fields=["gender"],
168168
assign_field_dict={
169+
"locale": Cases("id", {3: LocaleEnum.zh_CN, 4: LocaleEnum.en_US, 5: LocaleEnum.fr_FR}, default=""),
169170
"active": False,
170171
"name": RawSQL("CONCAT(LEFT(name, 26), ' [NEW]')"),
171172
"extend": {},
@@ -184,7 +185,7 @@ class UpdateIn(BaseModel):
184185
async def bulk_update_view(
185186
dicts: List[UpdateIn] = Body(..., embed=True),
186187
):
187-
row_cnt = await AccountMgr.bulk_update_with_fly_table(
188+
row_cnt = await AccountMgr.bulk_update(
188189
[d.dict() for d in dicts],
189190
join_fields=["id"],
190191
update_fields=["active", "gender"],

fastapi_esql/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@
1111
)
1212
from .utils import (
1313
CursorHandler,
14+
Cases,
1415
RawSQL,
1516
SQLizer,
1617
timing,
1718
)
1819

19-
__version__ = "0.0.3"
20+
__version__ = "0.0.4"
2021

2122
__all__ = [
2223
"QsParsingError",
@@ -25,6 +26,7 @@
2526
"BaseManager",
2627
"BaseModel",
2728
"CursorHandler",
29+
"Cases",
2830
"RawSQL",
2931
"SQLizer",
3032
"timing",

fastapi_esql/orm/base_manager.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,14 @@ async def update_json_field(
105105
return await CursorHandler.sum_row_cnt(sql, cls.rw_conn, logger)
106106

107107
@classmethod
108-
async def upsert_on_duplicated(
108+
async def upsert_on_duplicate(
109109
cls,
110110
dicts: List[Dict[str, Any]],
111111
insert_fields: List[str],
112112
upsert_fields: List[str],
113113
using_values: bool = False,
114114
):
115-
sql = SQLizer.upsert_on_duplicated(
115+
sql = SQLizer.upsert_on_duplicate(
116116
cls.table,
117117
dicts,
118118
insert_fields,
@@ -140,14 +140,14 @@ async def insert_into_select(
140140
return await CursorHandler.exec_if_ok(sql, cls.rw_conn, logger)
141141

142142
@classmethod
143-
async def bulk_update_with_fly_table(
143+
async def bulk_update(
144144
cls,
145145
dicts: List[Dict[str, Any]],
146146
join_fields: List[str],
147147
update_fields: List[str],
148148
using_values: bool = True,
149149
):
150-
sql = SQLizer.bulk_update_with_fly_table(
150+
sql = SQLizer.bulk_update(
151151
cls.table,
152152
dicts,
153153
join_fields,

fastapi_esql/utils/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
from .cursor_handler import CursorHandler
22
from .decorator import timing
3-
from .sqlizer import RawSQL, SQLizer
3+
from .sqlizer import Cases, RawSQL, SQLizer

fastapi_esql/utils/sqlizer.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,27 @@ def __init__(self, sql: str):
2020
self.sql = sql
2121

2222

23+
class Cases:
24+
"""
25+
Simple case statement, like:
26+
'CASE `feild` WHEN ... THEN ... ELSE <default> END'.
27+
If your statement is more complex, please use RawSQL directly.
28+
"""
29+
def __init__(self, field: str, whens: dict, default=None):
30+
self.field = field
31+
self.whens = whens
32+
self.default = default
33+
34+
@property
35+
def sql(self):
36+
whens = " ".join(
37+
f"WHEN {k} THEN {SQLizer._sqlize_value(v)}"
38+
for k, v in self.whens.items()
39+
)
40+
else_ = " ELSE " + SQLizer._sqlize_value(self.default) if self.default is not None else ""
41+
return f"CASE {self.field} {whens}{else_} END"
42+
43+
2344
class SQLizer:
2445

2546
@classmethod
@@ -68,7 +89,7 @@ def _sqlize_value(cls, value, to_json=False) -> str:
6889
"""
6990
if value is None:
7091
return "NULL"
71-
elif isinstance(value, RawSQL):
92+
elif isinstance(value, (Cases, RawSQL)):
7293
return value.sql
7394
elif isinstance(value, (int, float, bool)):
7495
return f"{value}"
@@ -158,7 +179,7 @@ def update_json_field(
158179
return sql
159180

160181
@classmethod
161-
def upsert_on_duplicated(
182+
def upsert_on_duplicate(
162183
cls,
163184
table: str,
164185
dicts: List[Dict[str, Any]],
@@ -254,7 +275,7 @@ def build_fly_table(
254275
return sql
255276

256277
@classmethod
257-
def bulk_update_with_fly_table(
278+
def bulk_update(
258279
cls,
259280
table: str,
260281
dicts: List[Dict[str, Any]],

0 commit comments

Comments
 (0)