kiba-core 0.5.3.dev90__tar.gz → 0.5.3.dev91__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.
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/store/entity_repository.py +12 -2
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/kiba_core.egg-info/PKG-INFO +1 -1
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/pyproject.toml +1 -1
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/test_entity_repository.py +43 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/.github/pull_request_template.md +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/.github/workflows/deploy.yml +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/.github/workflows/publish.yml +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/.github/workflows/pull-request.yml +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/.github/workflows/release.yml +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/.gitignore +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/CHANGELOG.md +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/Dockerfile +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/README.md +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/api_request.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/api_response.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/authorizer.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/default_routes.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/health.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/json_route.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/database_connection_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/exception_handling_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/logging_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/origin_ip_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/server_headers_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/openapi.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/rate_limit.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/request_body.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/request_context.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/route.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/route_auth.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/route_metadata.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/streaming_json_route.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/uploaded_file.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/aws_requester.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/caching/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/caching/cache.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/caching/dict_cache.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/caching/file_cache.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/cron/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/cron/api_request_cron_job_processor.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/cron/cron_executor.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/cron/cron_job_processor.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/cron/model.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/exceptions.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/http/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/http/basic_authentication.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/http/jwt.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/http/rest_method.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/locks/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/locks/lock.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/locks/model.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/locks/sql.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/logging.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/notifications/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/notifications/discord_client.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/notifications/notification_client.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/notifications/slack_client.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/py.typed +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/aqs.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/cosmos.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/message_queue.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/message_queue_processor.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/model.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/sql.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/queues/sqs.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/requester/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/requester/requester.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/s3_manager.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/service_client.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/store/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/store/database.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/store/retriever.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/store/saver.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/async_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/chain_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/date_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/dict_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/file_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/hashing_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/http_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/json_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/list_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/process_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/string_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/typing_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/url_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/util/value_holder.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/web3/eth_client.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/web3/eth_client_registry.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/web3/multicall3.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/kiba_core.egg-info/SOURCES.txt +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/kiba_core.egg-info/dependency_links.txt +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/kiba_core.egg-info/requires.txt +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/kiba_core.egg-info/top_level.txt +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/makefile +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/setup.cfg +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_api_response.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_authorizer.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_database_connection_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_exception_handling_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_json_route.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_openapi.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_origin_ip_middleware.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_rate_limit.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_request_context.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_route.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_streaming_json_route.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/caching/test_dict_cache.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/caching/test_file_cache.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/cron/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/cron/test_cron_executor.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/locks/test_sql_lock.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/queues/conftest.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/queues/test_aqs_queue.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/queues/test_cosmos_queue.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/queues/test_message_queue_processor.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/queues/test_sql_queue.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/queues/test_sqs_queue.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/requester/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/requester/test_requester.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/test_database.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/test_exceptions.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/test_logging.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_async_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_chain_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_date_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_dict_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_file_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_json_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_list_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_process_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_string_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/util/test_url_util.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/web3/__init__.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/web3/test_eth_client_registry.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/web3/test_rest_eth_client.py +0 -0
- {kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/uv.lock +0 -0
|
@@ -9,6 +9,7 @@ from sqlalchemy.dialects import sqlite as sqlalchemy_sqlite
|
|
|
9
9
|
from sqlalchemy.engine import Result
|
|
10
10
|
from sqlalchemy.engine import RowMapping
|
|
11
11
|
from sqlalchemy.sql import Select
|
|
12
|
+
from sqlalchemy.sql.base import ReadOnlyColumnCollection
|
|
12
13
|
|
|
13
14
|
from core.exceptions import KibaException
|
|
14
15
|
from core.exceptions import NotFoundException
|
|
@@ -25,6 +26,7 @@ from core.store.retriever import uuid_from_value
|
|
|
25
26
|
from core.util import date_util
|
|
26
27
|
|
|
27
28
|
EntityType = typing.TypeVar('EntityType', bound=BaseModel)
|
|
29
|
+
UpsertUpdateWhere = typing.Callable[[ReadOnlyColumnCollection[str, typing.Any]], sqlalchemy.ColumnElement[bool]] # type: ignore[explicit-any]
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
class EntityRepository(typing.Generic[EntityType]): # noqa: UP046
|
|
@@ -135,7 +137,8 @@ class EntityRepository(typing.Generic[EntityType]): # noqa: UP046
|
|
|
135
137
|
result = await database.execute(query=self.table.update().where(self.idColumn == idValue).values(updateValues).returning(*self.list_select_columns()), connection=connection)
|
|
136
138
|
return self.force_from_result(result=result)
|
|
137
139
|
|
|
138
|
-
|
|
140
|
+
# NOTE(krishan711): updateWhere gets the conflicting row's new values (`excluded`) and only updates when it is true; when it is false nothing is written and the stored row is returned
|
|
141
|
+
async def upsert(self, database: Database, constraintColumnNames: list[str], connection: DatabaseConnection | None = None, updateWhere: UpsertUpdateWhere | None = None, **kwargs) -> EntityType: # type: ignore[no-untyped-def] # noqa: ANN003
|
|
139
142
|
updateValues = self._create_values(kwargs=kwargs, shouldAddUpdatedDate=True, shouldAddCreatedDate=False)
|
|
140
143
|
insertValues = self._create_values(kwargs=kwargs, shouldAddUpdatedDate=True, shouldAddCreatedDate=True)
|
|
141
144
|
self._add_generated_id(values=insertValues)
|
|
@@ -144,9 +147,16 @@ class EntityRepository(typing.Generic[EntityType]): # noqa: UP046
|
|
|
144
147
|
doUpdateStatement = insertStatement.on_conflict_do_update(
|
|
145
148
|
index_elements=constraintColumns,
|
|
146
149
|
set_=updateValues,
|
|
150
|
+
where=updateWhere(insertStatement.excluded) if updateWhere is not None else None,
|
|
147
151
|
)
|
|
148
152
|
result = await database.execute(query=doUpdateStatement.returning(*self.list_select_columns()), connection=connection)
|
|
149
|
-
|
|
153
|
+
row = result.mappings().first()
|
|
154
|
+
if row is None and updateWhere is not None:
|
|
155
|
+
storedQuery = self.build_select().where(*[column == insertValues[column] for column in constraintColumns])
|
|
156
|
+
row = (await database.execute(query=storedQuery, connection=connection)).mappings().first()
|
|
157
|
+
if row is None:
|
|
158
|
+
raise NotFoundException
|
|
159
|
+
return self.from_row(row=row)
|
|
150
160
|
|
|
151
161
|
async def upsert_many(self, database: Database, constraintColumnNames: list[str], rowDicts: list[dict[str, typing.Any]], connection: DatabaseConnection | None = None) -> list[EntityType]: # type: ignore[explicit-any]
|
|
152
162
|
if not rowDicts:
|
|
@@ -172,6 +172,49 @@ async def test_upsert_inserts_then_updates(database: Database):
|
|
|
172
172
|
assert upsertedItem.count == 2
|
|
173
173
|
|
|
174
174
|
|
|
175
|
+
async def test_upsert_with_false_update_where_keeps_and_returns_the_stored_row(database: Database):
|
|
176
|
+
item = await _create_item(database=database, name='a', count=1)
|
|
177
|
+
async with database.create_transaction() as connection:
|
|
178
|
+
upsertedItem = await ItemsRepository.upsert(database=database, connection=connection, constraintColumnNames=['name'], updateWhere=lambda excluded: excluded.count > ItemsTable.c.count, name='a', count=0, amount=5)
|
|
179
|
+
storedItem = await ItemsRepository.get(database=database, connection=connection, idValue=item.itemId)
|
|
180
|
+
assert upsertedItem == item
|
|
181
|
+
assert storedItem == item
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
async def test_upsert_with_false_update_where_finds_the_stored_row_by_converted_constraint_values(database: Database):
|
|
185
|
+
repository = UpperNameEntityRepository(table=ItemsTable, modelClass=Item)
|
|
186
|
+
async with database.create_transaction() as connection:
|
|
187
|
+
item = await repository.create(database=database, connection=connection, name='a', count=1, amount=1)
|
|
188
|
+
upsertedItem = await repository.upsert(database=database, connection=connection, constraintColumnNames=['name'], updateWhere=lambda _excluded: sqlalchemy.false(), name='a', count=2, amount=1)
|
|
189
|
+
assert upsertedItem == item
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
async def test_upsert_with_true_update_where_updates_the_row(database: Database):
|
|
193
|
+
item = await _create_item(database=database, name='a', count=1)
|
|
194
|
+
async with database.create_transaction() as connection:
|
|
195
|
+
upsertedItem = await ItemsRepository.upsert(database=database, connection=connection, constraintColumnNames=['name'], updateWhere=lambda excluded: excluded.count > ItemsTable.c.count, name='a', count=2, amount=5)
|
|
196
|
+
assert (upsertedItem.itemId, upsertedItem.createdDate, upsertedItem.count, upsertedItem.amount) == (item.itemId, item.createdDate, 2, 5)
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
async def test_upsert_with_update_where_still_inserts_new_rows(database: Database):
|
|
200
|
+
async with database.create_transaction() as connection:
|
|
201
|
+
upsertedItem = await ItemsRepository.upsert(database=database, connection=connection, constraintColumnNames=['name'], updateWhere=lambda _excluded: sqlalchemy.false(), name='a', count=1, amount=1)
|
|
202
|
+
storedItems = await ItemsRepository.list_many(database=database, connection=connection, fieldFilters=[])
|
|
203
|
+
assert storedItems == [upsertedItem]
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
async def test_upsert_only_when_values_changed(database: Database):
|
|
207
|
+
def changed(excluded: typing.Any) -> sqlalchemy.ColumnElement[bool]: # type: ignore[explicit-any]
|
|
208
|
+
return sqlalchemy.or_(ItemsTable.c.count.is_distinct_from(excluded.count), ItemsTable.c.expiryDate.is_distinct_from(excluded.expiryDate))
|
|
209
|
+
|
|
210
|
+
async with database.create_transaction() as connection:
|
|
211
|
+
item = await ItemsRepository.upsert(database=database, connection=connection, constraintColumnNames=['name'], updateWhere=changed, name='a', count=1, amount=1, expiryDate=None)
|
|
212
|
+
unchangedItem = await ItemsRepository.upsert(database=database, connection=connection, constraintColumnNames=['name'], updateWhere=changed, name='a', count=1, amount=1, expiryDate=None)
|
|
213
|
+
changedItem = await ItemsRepository.upsert(database=database, connection=connection, constraintColumnNames=['name'], updateWhere=changed, name='a', count=1, amount=1, expiryDate=datetime.datetime(2030, 1, 1, tzinfo=datetime.UTC))
|
|
214
|
+
assert unchangedItem == item
|
|
215
|
+
assert (changedItem.itemId, changedItem.expiryDate) == (item.itemId, datetime.datetime(2030, 1, 1, tzinfo=datetime.UTC))
|
|
216
|
+
|
|
217
|
+
|
|
175
218
|
async def test_upsert_many_inserts_and_updates(database: Database):
|
|
176
219
|
item = await _create_item(database=database, name='a')
|
|
177
220
|
async with database.create_transaction() as connection:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/exception_handling_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/core/api/middleware/server_headers_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_database_connection_middleware.py
RENAMED
|
File without changes
|
{kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/api/test_exception_handling_middleware.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kiba_core-0.5.3.dev90 → kiba_core-0.5.3.dev91}/tests/queues/test_message_queue_processor.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|