Skip to content

Commit 7862cd8

Browse files
authored
Export COMMIT_TIMESTAMP constant. (googleapis#5102)
Magic string value for timestamp columns to be populated on the backend with the commit timestamp of the corresponding insert / update operation. Add a system test which shows using it with a table whose 'commit_ts' column supports it.
1 parent cd8a69b commit 7862cd8

File tree

4 files changed

+50
-0
lines changed

4 files changed

+50
-0
lines changed

spanner/google/cloud/spanner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from google.cloud.spanner_v1 import AbstractSessionPool
2121
from google.cloud.spanner_v1 import BurstyPool
2222
from google.cloud.spanner_v1 import Client
23+
from google.cloud.spanner_v1 import COMMIT_TIMESTAMP
2324
from google.cloud.spanner_v1 import enums
2425
from google.cloud.spanner_v1 import FixedSizePool
2526
from google.cloud.spanner_v1 import KeyRange
@@ -33,6 +34,7 @@
3334
'AbstractSessionPool',
3435
'BurstyPool',
3536
'Client',
37+
'COMMIT_TIMESTAMP',
3638
'enums',
3739
'FixedSizePool',
3840
'KeyRange',

spanner/google/cloud/spanner_v1/__init__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,14 @@
2828
from google.cloud.spanner_v1.pool import FixedSizePool
2929

3030

31+
COMMIT_TIMESTAMP = 'spanner.commit_timestamp()'
32+
"""Placeholder be used to store commit timestamp of a transaction in a column.
33+
34+
This value can only be used for timestamp columns that have set the option
35+
``(allow_commit_timestamp=true)`` in the schema.
36+
"""
37+
38+
3139
__all__ = (
3240
# google.cloud.spanner_v1
3341
'__version__',
@@ -48,4 +56,7 @@
4856

4957
# google.cloud.spanner_v1.gapic
5058
'enums',
59+
60+
# local
61+
'COMMIT_TIMESTAMP',
5162
)

spanner/tests/_fixtures.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,14 @@
4848
tags ARRAY<STRING(16)> )
4949
PRIMARY KEY (id);
5050
CREATE INDEX name ON contacts(first_name, last_name);
51+
CREATE TABLE users_history (
52+
id INT64 NOT NULL,
53+
commit_ts TIMESTAMP NOT NULL OPTIONS
54+
(allow_commit_timestamp=true),
55+
name STRING(MAX) NOT NULL,
56+
email STRING(MAX),
57+
deleted BOOL NOT NULL )
58+
PRIMARY KEY(id, commit_ts DESC);
5159
"""
5260

5361
DDL_STATEMENTS = [stmt.strip() for stmt in DDL.split(';') if stmt.strip()]

spanner/tests/system/test_system.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
from google.cloud.spanner import KeyRange
3939
from google.cloud.spanner import KeySet
4040
from google.cloud.spanner import BurstyPool
41+
from google.cloud.spanner import COMMIT_TIMESTAMP
4142

4243
from test_utils.retry import RetryErrors
4344
from test_utils.retry import RetryInstanceState
@@ -512,6 +513,34 @@ def test_batch_insert_or_update_then_query(self):
512513
rows = list(snapshot.execute_sql(self.SQL))
513514
self._check_rows_data(rows)
514515

516+
def test_batch_insert_w_commit_timestamp(self):
517+
retry = RetryInstanceState(_has_all_ddl)
518+
retry(self._db.reload)()
519+
520+
table = 'users_history'
521+
columns = ['id', 'commit_ts', 'name', 'email', 'deleted']
522+
user_id = 1234
523+
name = 'phred'
524+
email = 'phred@example.com'
525+
row_data = [
526+
[user_id, COMMIT_TIMESTAMP, name, email, False],
527+
]
528+
529+
with self._db.batch() as batch:
530+
batch.delete(table, self.ALL)
531+
batch.insert(table, columns, row_data)
532+
533+
with self._db.snapshot(read_timestamp=batch.committed) as snapshot:
534+
rows = list(snapshot.read(table, columns, self.ALL))
535+
536+
self.assertEqual(len(rows), 1)
537+
r_id, commit_ts, r_name, r_email, deleted = rows[0]
538+
self.assertEqual(r_id, user_id)
539+
self.assertEqual(commit_ts, batch.committed)
540+
self.assertEqual(r_name, name)
541+
self.assertEqual(r_email, email)
542+
self.assertFalse(deleted)
543+
515544
@RetryErrors(exception=exceptions.ServerError)
516545
def test_transaction_read_and_insert_then_rollback(self):
517546
retry = RetryInstanceState(_has_all_ddl)

0 commit comments

Comments
 (0)