(Data): Small extensions to core data interfaces.

Add `LEQ` condition type.
Ensure that batch updates don't fire with nothing to update.
Add `cast_row` to `update_many` for handling typed `NULL`s.
This commit is contained in:
2021-09-19 09:54:08 +03:00
parent fa2435e93a
commit 4229fe8b18
3 changed files with 20 additions and 3 deletions

View File

@@ -45,6 +45,21 @@ class GEQ(Condition):
values.append(item)
class LEQ(Condition):
__slots__ = ('value',)
def __init__(self, value):
self.value = value
def apply(self, key, values, conditions):
item = self.value
if isinstance(item, (list, tuple)):
raise ValueError("Cannot apply LEQ condition to a list!")
else:
conditions.append("{} <= {}".format(key, _replace_char))
values.append(item)
class Constant(Condition):
__slots__ = ('value',)

View File

@@ -113,7 +113,8 @@ class Row:
try:
yield self._pending
finally:
self.update(**self._pending)
if self._pending:
self.update(**self._pending)
self._pending = None
def _refresh(self):

View File

@@ -126,7 +126,7 @@ def upsert(table, constraint, cursor=None, **values):
return cursor.fetchone()
def update_many(table, *values, set_keys=None, where_keys=None, cursor=None):
def update_many(table, *values, set_keys=None, where_keys=None, cast_row=None, cursor=None):
cursor = cursor or conn.cursor()
return execute_values(
@@ -134,13 +134,14 @@ def update_many(table, *values, set_keys=None, where_keys=None, cursor=None):
"""
UPDATE {table}
SET {set_clause}
FROM (VALUES %s)
FROM (VALUES {cast_row}%s)
AS {temp_table}
WHERE {where_clause}
RETURNING *
""".format(
table=table,
set_clause=', '.join("{0} = _t.{0}".format(key) for key in set_keys),
cast_row=cast_row + ',' if cast_row else '',
where_clause=' AND '.join("{1}.{0} = _t.{0}".format(key, table) for key in where_keys),
temp_table="_t ({})".format(', '.join(set_keys + where_keys))
),