Skip to content

Commit b75a90f

Browse files
committed
feat: add new param assign_field_dict to update_json_field
1 parent b274011 commit b75a90f

File tree

4 files changed

+56
-5
lines changed

4 files changed

+56
-5
lines changed

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,17 @@ await AccountMgr.update_json_field(
106106
},
107107
remove_paths=["$.deprecated"],
108108
json_type=dict,
109+
assign_field_dict={
110+
"active": True,
111+
"name": "new_name",
112+
},
109113
)
110114
```
111115
Generate sql and execute
112116
```sql
113117
UPDATE `account` SET extend =
114118
JSON_MERGE_PATCH(JSON_SET(JSON_REMOVE(COALESCE(extend, '{}'), '$.deprecated'), '$.last_login',CAST('{"ipv4": "209.182.101.161"}' AS JSON), '$.uuid','fd04f7f2-24fc-4a73-a1d7-b6e99a464c5f'), '{"updated_at": "2022-10-30 21:34:15", "info": {"online_sec": 636}}')
119+
, active=True, name='new_name'
115120
WHERE `id`=8
116121
```
117122

fastapi_esql/orm/base_manager.py

+2
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ async def update_json_field(
133133
path_value_dict: Optional[Dict[str, Any]] = None,
134134
remove_paths: Optional[List[str]] = None,
135135
json_type: type = dict,
136+
assign_field_dict: Dict[str, Any] = None,
136137
):
137138
sql = SQLizer.update_json_field(
138139
cls.table,
@@ -142,6 +143,7 @@ async def update_json_field(
142143
path_value_dict=path_value_dict,
143144
remove_paths=remove_paths,
144145
json_type=json_type,
146+
assign_field_dict=assign_field_dict,
145147
model=cls.model,
146148
)
147149
return await CursorHandler.sum_row_cnt(sql, cls.rw_conn, logger)

fastapi_esql/utils/sqlizer.py

+18-5
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ def update_json_field(
162162
path_value_dict: Optional[Dict[str, Any]] = None,
163163
remove_paths: Optional[List[str]] = None,
164164
json_type: type = dict,
165+
assign_field_dict: Dict[str, Any] = None,
165166
model: Optional[Model] = None,
166167
) -> Optional[str]:
167168
if not all([table, json_field, wheres]):
@@ -184,11 +185,23 @@ def update_json_field(
184185
if merge_dict:
185186
json_obj = f"JSON_MERGE_PATCH({json_obj}, {cls.sqlize_value(merge_dict)})"
186187

187-
sql = f"""
188-
UPDATE {wrap_backticks(table)} SET {json_field} =
189-
{json_obj}
190-
WHERE {cls.resolve_wheres(wheres, model)}
191-
"""
188+
assign_field_dict = assign_field_dict or {}
189+
assign_fields = []
190+
for k, v in assign_field_dict.items():
191+
assign_fields.append(f"{k}={cls.sqlize_value(v)}")
192+
assign_field = ", ".join(assign_fields) if assign_fields else None
193+
194+
sql = """
195+
UPDATE {} SET {} =
196+
{}{}
197+
WHERE {}
198+
""".format(
199+
wrap_backticks(table),
200+
json_field,
201+
json_obj,
202+
"\n , " + assign_field if assign_field else "",
203+
cls.resolve_wheres(wheres, model),
204+
)
192205
logger.debug(sql)
193206
return sql
194207

tests/test_sqlizer.py

+31
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,37 @@ def test_update_json_field(self):
200200
WHERE `id`=8
201201
"""
202202

203+
sql = SQLizer.update_json_field(
204+
self.table,
205+
json_field="extend",
206+
wheres=Q(id=8),
207+
merge_dict={
208+
"updated_at": "2022-10-30 21:34:15",
209+
"info": {
210+
"online_sec": 636,
211+
}
212+
},
213+
path_value_dict={
214+
"$.last_login": {
215+
"ipv4": "209.182.101.161",
216+
},
217+
"$.uuid": "fd04f7f2-24fc-4a73-a1d7-b6e99a464c5f",
218+
},
219+
remove_paths=["$.deprecated"],
220+
json_type=dict,
221+
assign_field_dict={
222+
"active": True,
223+
"name": "new_name",
224+
},
225+
model=self.model,
226+
)
227+
assert sql == """
228+
UPDATE `account` SET extend =
229+
JSON_MERGE_PATCH(JSON_SET(JSON_REMOVE(COALESCE(extend, '{}'), '$.deprecated'), '$.last_login',CAST('{"ipv4": "209.182.101.161"}' AS JSON), '$.uuid','fd04f7f2-24fc-4a73-a1d7-b6e99a464c5f'), '{"updated_at": "2022-10-30 21:34:15", "info": {"online_sec": 636}}')
230+
, active=True, name='new_name'
231+
WHERE `id`=8
232+
"""
233+
203234
def test_upsert_on_duplicate(self):
204235
with self.assertRaises(WrongParamsError):
205236
SQLizer.upsert_on_duplicate(

0 commit comments

Comments
 (0)