tracktolib 0.50.0__tar.gz → 0.51.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tracktolib
3
- Version: 0.50.0
3
+ Version: 0.51.0
4
4
  Summary: Utility library for python
5
5
  Home-page: https://github.com/tracktor/tracktolib
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "tracktolib"
3
- version = "0.50.0"
3
+ version = "0.51.0"
4
4
  description = "Utility library for python"
5
5
  authors = ["Julien Brayere <julien.brayere@tracktor.fr>"]
6
6
  license = "MIT"
@@ -81,7 +81,7 @@ pythonPlatform = "Linux"
81
81
 
82
82
  [tool.commitizen]
83
83
  name = "cz_conventional_commits"
84
- version = "0.50.0"
84
+ version = "0.51.0"
85
85
  tag_format = "$version"
86
86
  version_files = [
87
87
  "pyproject.toml:version"
@@ -75,6 +75,7 @@ class PGConflictQuery(Generic[K]):
75
75
  query: str | None = None
76
76
  constraint: str | None = None
77
77
  where: str | None = None
78
+ """JSONB keys to merge (like jsonb1 || newjsonb2)"""
78
79
  merge_keys: Iterable[K] | None = None
79
80
 
80
81
  def __post_init__(self):
@@ -198,17 +199,30 @@ def get_update_fields(
198
199
  start_from: int = 0,
199
200
  ignore_keys: list[str] | None = None,
200
201
  quote_columns: bool = False,
202
+ merge_keys: list[str] | None = None,
201
203
  ) -> tuple[str, list]:
202
204
  values, fields, where_values = [], [], []
203
205
  counter = 0
206
+ _merge_keys = set(merge_keys or [])
207
+ _ignore_keys = ignore_keys or []
208
+
209
+ _invalid_merge_keys = _merge_keys - set(keys)
210
+ if _invalid_merge_keys:
211
+ raise ValueError(f"Merge keys not in keys found: {_invalid_merge_keys}")
212
+
204
213
  for k in keys:
205
214
  v = item[k]
206
- if ignore_keys and k in ignore_keys:
215
+ if k in _ignore_keys:
207
216
  where_values.append(v)
208
217
  continue
209
218
  values.append(v)
210
219
  _col = f'"{k}"' if quote_columns else k
211
- fields.append(f"{_col} = ${counter + start_from + 1}")
220
+ _counter = counter + start_from + 1
221
+ fields.append(
222
+ f"{_col} = ${_counter}"
223
+ if k not in _merge_keys
224
+ else f"{_col} = COALESCE(t.{_col}, jsonb_build_object()) || " f"${_counter}"
225
+ )
212
226
  counter += 1
213
227
  return ",\n".join(fields), values + where_values
214
228
 
@@ -227,6 +241,8 @@ class PGUpdateQuery(PGQuery):
227
241
  returning: str | list[str] | None = None
228
242
  """If True, the query will return all the updated fields"""
229
243
  return_keys: bool = False
244
+ """Values to update using merge (like {}::jsonb || {}::jsonb)"""
245
+ merge_keys: list[str] | None = None
230
246
 
231
247
  _update_fields: str | None = field(init=False, default=None)
232
248
  _values: list | None = field(init=False, default=None)
@@ -243,6 +259,7 @@ class PGUpdateQuery(PGQuery):
243
259
  start_from=self.start_from or 0,
244
260
  ignore_keys=self.where_keys,
245
261
  quote_columns=self.quote_columns,
262
+ merge_keys=self.merge_keys,
246
263
  )
247
264
  if self.returning and self.return_keys:
248
265
  raise ValueError("Please choose either returning or return_keys")
@@ -268,7 +285,7 @@ class PGUpdateQuery(PGQuery):
268
285
  raise ValueError("No update fields found")
269
286
 
270
287
  query = f"""
271
- UPDATE {self.table}
288
+ UPDATE {self.table} t
272
289
  SET {self._update_fields}
273
290
  {self._get_where_query()}
274
291
  """
@@ -375,8 +392,13 @@ async def update_one(
375
392
  keys: list[str] | None = None,
376
393
  start_from: int | None = None,
377
394
  where: str | None = None,
395
+ merge_keys: list[str] | None = None,
378
396
  ):
379
- query = PGUpdateQuery(table=table, items=[item], start_from=start_from, where_keys=keys, where=where)
397
+ query = PGUpdateQuery(
398
+ table=table, items=[item], start_from=start_from, where_keys=keys, where=where, merge_keys=merge_keys
399
+ )
400
+ print(query.query)
401
+ print(query.values)
380
402
  await conn.execute(query.query, *args, *query.values)
381
403
 
382
404
 
@@ -391,6 +413,7 @@ async def update_returning(
391
413
  where: str | None = None,
392
414
  keys: list[str] | None = None,
393
415
  start_from: int | None = None,
416
+ merge_keys: list[str] | None = None,
394
417
  ) -> Any | None: ...
395
418
 
396
419
 
@@ -405,6 +428,7 @@ async def update_returning(
405
428
  where: str | None = None,
406
429
  keys: list[str] | None = None,
407
430
  start_from: int | None = None,
431
+ merge_keys: list[str] | None = None,
408
432
  ) -> asyncpg.Record | None: ...
409
433
 
410
434
 
@@ -419,6 +443,7 @@ async def update_returning(
419
443
  where: str | None = None,
420
444
  keys: list[str] | None = None,
421
445
  start_from: int | None = None,
446
+ merge_keys: list[str] | None = None,
422
447
  ) -> asyncpg.Record | None: ...
423
448
 
424
449
 
@@ -432,6 +457,7 @@ async def update_returning(
432
457
  where: str | None = None,
433
458
  keys: list[str] | None = None,
434
459
  start_from: int | None = None,
460
+ merge_keys: list[str] | None = None,
435
461
  ) -> Any | asyncpg.Record | None:
436
462
  if returning is not None:
437
463
  returning_values = [returning] if isinstance(returning, str) else returning
@@ -445,6 +471,7 @@ async def update_returning(
445
471
  where_keys=keys,
446
472
  return_keys=return_keys,
447
473
  returning=returning_values,
474
+ merge_keys=merge_keys,
448
475
  )
449
476
  fn = conn.fetchval if len(returning_values or []) == 1 else conn.fetchrow
450
477
  return await fn(query.query, *args, *query.values)
@@ -69,6 +69,7 @@ def get_conflict_query(
69
69
  _ignore_columns = [*_update_columns, *_ignore_columns, *_merge_columns]
70
70
  fields = ", ".join(f"{x} = COALESCE(EXCLUDED.{x}, t.{x})" for x in columns if x not in _ignore_columns)
71
71
  if merge_columns:
72
+ fields = fields + ", " if fields else fields
72
73
  fields += ", ".join(f"{x} = COALESCE(t.{x}, jsonb_build_object()) || EXCLUDED.{x}" for x in merge_columns)
73
74
  if not fields:
74
75
  raise ValueError("No fields set")
File without changes
File without changes