Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions datastore/gcloud/aio/datastore/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,11 @@ class QueryResult:
query_result_batch_kind = QueryResultBatch

def __init__(self, result_batch: Optional[QueryResultBatch] = None,
explain_metrics: Optional[ExplainMetrics] = None):
explain_metrics: Optional[ExplainMetrics] = None,
transaction: Optional[str] = None):
self.result_batch = result_batch
self.explain_metrics = explain_metrics
self.transaction = transaction

def __repr__(self) -> str:
return str(self.to_repr())
Expand All @@ -293,27 +295,33 @@ def __eq__(self, other: object) -> bool:
if not isinstance(other, QueryResult):
return False
return (self.result_batch == other.result_batch
and self.explain_metrics == other.explain_metrics)
and self.explain_metrics == other.explain_metrics
and self.transaction == other.transaction)

@classmethod
def from_repr(cls, data: Dict[str, Any]) -> 'QueryResult':
result_batch = None
explain_metrics = None
transaction = None

if 'batch' in data:
result_batch = cls.query_result_batch_kind.from_repr(data['batch'])
if 'explainMetrics' in data:
explain_metrics = ExplainMetrics.from_repr(data['explainMetrics'])
if 'transaction' in data:
transaction = data['transaction']

return cls(result_batch=result_batch, explain_metrics=explain_metrics)
return cls(result_batch=result_batch,
explain_metrics=explain_metrics, transaction=transaction)

def to_repr(self) -> Dict[str, Any]:
result = {}
result: Dict[str, Any] = {}
if self.result_batch:
result['batch'] = self.result_batch.to_repr()
if self.explain_metrics:
result['explainMetrics'] = self.explain_metrics.to_repr()

if self.transaction:
result['transaction'] = self.transaction
return result

def get_explain_metrics(self) -> Optional[ExplainMetrics]:
Expand Down
2 changes: 1 addition & 1 deletion datastore/pyproject.rest.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "gcloud-rest-datastore"
version = "9.0.0"
version = "9.1.0"
description = "Python Client for Google Cloud Datastore"
readme = "README.rst"

Expand Down
2 changes: 1 addition & 1 deletion datastore/pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "gcloud-aio-datastore"
version = "9.0.0"
version = "9.1.0"
description = "Python Client for Google Cloud Datastore"
readme = "README.rst"

Expand Down
47 changes: 47 additions & 0 deletions datastore/tests/integration/smoke_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,53 @@ async def test_start_transaction_on_lookup(creds: str,
actual = await ds.lookup([key], session=s)
assert actual['found'][0].entity.properties == {'animal': 'aardvark'}

# Clean up test data
await ds.delete(key, s)


@pytest.mark.asyncio
async def test_start_transaction_on_query(
creds: str, kind: str, project: str,
) -> None:
key = Key(project, [PathElement(kind, name=f'test_record_{uuid.uuid4()}')])

async with Session() as s:
ds = Datastore(project=project, service_file=creds, session=s)

# Test query with newTransaction parameter
property_filter = PropertyFilter(
prop='animal',
operator=PropertyFilterOperator.EQUAL,
value=Value('three-toed sloth'),
)
query = Query(kind=kind, query_filter=Filter(property_filter))

# Use newTransaction parameter
options = TransactionOptions(ReadWrite())
result = await ds.runQuery(query, newTransaction=options, session=s)
assert result.transaction is not None and result.transaction

mutations = [
ds.make_mutation(
Operation.INSERT, key,
properties={'animal': 'three-toed sloth'},
),
ds.make_mutation(
Operation.UPDATE, key,
properties={'animal': 'aardvark'},
),
]
await ds.commit(
mutations,
transaction=result.transaction,
session=s)

actual = await ds.lookup([key], session=s)
assert actual['found'][0].entity.properties == {'animal': 'aardvark'}

# Clean up test data
await ds.delete(key, s)


@pytest.mark.asyncio
async def test_transaction(creds: str, kind: str, project: str) -> None:
Expand Down