googleapis/python-spanner

Timestamps before 1000AD rejected in mutation API

c2nes opened this issue · 0 comments

Timestamp before the year 1000AD are rejected due to the year not being padded to 4 digits.

Code example

import datetime
from google.cloud import spanner

spanner_client = spanner.Client()
instance = spanner_client.instance(instance_id)
database = instance.database(database_id)


# spanner> show create table timestamps;
# +------------+---------------------------+
# | Table      | Create Table              |
# +------------+---------------------------+
# | timestamps | CREATE TABLE timestamps ( |
# |            |   k TIMESTAMP,            |
# |            | ) PRIMARY KEY(k)          |
# +------------+---------------------------+
# 1 rows in set (0.07 sec)

def run(txn, t):
    print("Inserting", t, "...")
    txn.insert(table="timestamps", columns=("k",), values=[(t,)])

t = datetime.datetime.now(datetime.UTC)
database.run_in_transaction(run, t)
database.run_in_transaction(run, t.replace(year=800))

Stack trace

Inserting 2024-04-15 20:19:45.990303+00:00 ...
Inserting 0800-04-15 20:19:45.990303+00:00 ...
Traceback (most recent call last):
  File "/tmp/mkplay.9k0dWG/t.py", line 38, in <module>
    database.run_in_transaction(run, t.replace(year=800))
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/cloud/spanner_v1/database.py", line 843, in run_in_transaction
    return session.run_in_transaction(func, *args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/cloud/spanner_v1/session.py", line 403, in run_in_transaction
    txn.commit(
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/cloud/spanner_v1/transaction.py", line 248, in commit
    response = _retry(
               ^^^^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/cloud/spanner_v1/_helpers.py", line 339, in _retry
    raise exc
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/cloud/spanner_v1/_helpers.py", line 325, in _retry
    return func()
           ^^^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/cloud/spanner_v1/services/spanner/client.py", line 1810, in commit
    response = rpc(
               ^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/api_core/gapic_v1/method.py", line 131, in __call__
    return wrapped_func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/api_core/retry/retry_unary.py", line 293, in retry_wrapped_func
    return retry_target(
           ^^^^^^^^^^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/api_core/retry/retry_unary.py", line 153, in retry_target
    _retry_error_helper(
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/api_core/retry/retry_base.py", line 212, in _retry_error_helper
    raise final_exc from source_exc
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/api_core/retry/retry_unary.py", line 144, in retry_target
    result = target()
             ^^^^^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/api_core/timeout.py", line 120, in func_with_timeout
    return func(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^
  File "/tmp/mkplay.9k0dWG/lib/python3.11/site-packages/google/api_core/grpc_helpers.py", line 78, in error_remapped_callable
    raise exceptions.from_grpc_error(exc) from exc
google.api_core.exceptions.FailedPrecondition: 400 Invalid value for column k in table timestamps: Expected TIMESTAMP.