# Path: spanner_orm/error.py
# class SpannerError(Exception):
# class ValidationError(Exception):
# 
# Path: spanner_orm/field.py
# class FieldType(abc.ABC):
# class Field(object):
# class Boolean(FieldType):
# class Integer(FieldType):
# class Float(FieldType):
# class String(FieldType):
# class StringArray(FieldType):
# class Timestamp(FieldType):
# class BytesBase64(FieldType):
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def __init__(self,
#                field_type: Type[FieldType],
#                nullable: bool = False,
#                primary_key: bool = False):
#   def ddl(self) -> str:
#   def field_type(self) -> Type[FieldType]:
#   def grpc_type(self) -> str:
#   def nullable(self) -> bool:
#   def primary_key(self) -> bool:
#   def validate(self, value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
# ALL_TYPES = [
#     Boolean, Integer, Float, String, StringArray, Timestamp, BytesBase64
# ]
# 
# Path: spanner_orm/testlib/spanner_emulator/testlib.py
# def _make_emulator_spanner_orm_connection(
#     db: database.Database, inst: instance.Instance,
#     spanner_client: client.Client) -> spanner_orm.SpannerConnection:
# def _get_instance(spanner_client: client.Client) -> instance.Instance:
# def _migrate_database_at_connection(connection: spanner_orm.SpannerConnection,
#                                     migrations_dir: str) -> None:
# def _database_id() -> str:
#   def setUpClass(cls):
#   def setUp(self):
#   def tearDownClass(cls):
#   def run_orm_migrations(self, migrations_folder: str) -> None:
# class TestCase(unittest.TestCase):
# 
# Path: spanner_orm/tests/models.py
# class SmallTestModel(model.Model):
# class SmallTestModelWithoutSecondaryIndexes(model.Model):
# class ChildTestModel(model.Model):
# class IndexTestModel(model.Model):
# class RelationshipTestModel(model.Model):
# class ForeignKeyTestModel(model.Model):
# class InheritanceTestModel(SmallTestModel):
# class UnittestModel(model.Model):
# class UnittestModelWithoutSecondaryIndexes(model.Model):
# class NullFilteredIndexModel(model.Model):


import datetime
import logging
import os
import typing
import unittest
from typing import List
from unittest import mock
from absl.testing import parameterized
from google.api_core import exceptions
from google.cloud import spanner  # pytype: disable=import-error
from spanner_orm import error
from spanner_orm import field
from spanner_orm.testlib.spanner_emulator import testlib as spanner_emulator_testlib
from spanner_orm.tests import models
    self.assert_api_called(update, mock_transaction)

  @mock.patch('spanner_orm.table_apis.upsert')
  def test_save_batch_force_write_upserts(self, upsert):
    mock_transaction = mock.Mock()
    values = {'key': 'key', 'value_1': 'value'}
    not_persisted = models.SmallTestModel(values)
    models.SmallTestModel.save_batch(
        [not_persisted],
        force_write=True,
        transaction=mock_transaction,
    )
    self.assert_api_called(upsert, mock_transaction)

  @mock.patch('spanner_orm.table_apis.delete')
  def test_delete_batch_deletes(self, delete):
    mock_transaction = mock.Mock()
    values = {'key': 'key', 'value_1': 'value'}
    model = models.SmallTestModel(values)
    models.SmallTestModel.delete_batch([model], transaction=mock_transaction)

    delete.assert_called_once()
    (transaction, table, keyset), _ = delete.call_args
    self.assertEqual(transaction, mock_transaction)
    self.assertEqual(table, models.SmallTestModel.table)
    self.assertEqual(keyset.keys, [[model.key]])

  @mock.patch('spanner_orm.table_apis.delete')
  def test_delete_by_key_deletes(self, delete):
    mock_transaction = mock.Mock()

# Path: spanner_orm/error.py
# class SpannerError(Exception):
# class ValidationError(Exception):
# 
# Path: spanner_orm/field.py
# class FieldType(abc.ABC):
# class Field(object):
# class Boolean(FieldType):
# class Integer(FieldType):
# class Float(FieldType):
# class String(FieldType):
# class StringArray(FieldType):
# class Timestamp(FieldType):
# class BytesBase64(FieldType):
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def __init__(self,
#                field_type: Type[FieldType],
#                nullable: bool = False,
#                primary_key: bool = False):
#   def ddl(self) -> str:
#   def field_type(self) -> Type[FieldType]:
#   def grpc_type(self) -> str:
#   def nullable(self) -> bool:
#   def primary_key(self) -> bool:
#   def validate(self, value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value: Any) -> None:
#   def ddl() -> str:
#   def grpc_type() -> type_pb2.Type:
#   def validate_type(value) -> None:
# ALL_TYPES = [
#     Boolean, Integer, Float, String, StringArray, Timestamp, BytesBase64
# ]
# 
# Path: spanner_orm/testlib/spanner_emulator/testlib.py
# def _make_emulator_spanner_orm_connection(
#     db: database.Database, inst: instance.Instance,
#     spanner_client: client.Client) -> spanner_orm.SpannerConnection:
# def _get_instance(spanner_client: client.Client) -> instance.Instance:
# def _migrate_database_at_connection(connection: spanner_orm.SpannerConnection,
#                                     migrations_dir: str) -> None:
# def _database_id() -> str:
#   def setUpClass(cls):
#   def setUp(self):
#   def tearDownClass(cls):
#   def run_orm_migrations(self, migrations_folder: str) -> None:
# class TestCase(unittest.TestCase):
# 
# Path: spanner_orm/tests/models.py
# class SmallTestModel(model.Model):
# class SmallTestModelWithoutSecondaryIndexes(model.Model):
# class ChildTestModel(model.Model):
# class IndexTestModel(model.Model):
# class RelationshipTestModel(model.Model):
# class ForeignKeyTestModel(model.Model):
# class InheritanceTestModel(SmallTestModel):
# class UnittestModel(model.Model):
# class UnittestModelWithoutSecondaryIndexes(model.Model):
# class NullFilteredIndexModel(model.Model):


# Path: spanner_orm/tests/model_test.py
import datetime
import logging
import os
import typing
import unittest
from typing import List
from unittest import mock
from absl.testing import parameterized
from google.api_core import exceptions
from google.cloud import spanner  # pytype: disable=import-error
from spanner_orm import error
from spanner_orm import field
from spanner_orm.testlib.spanner_emulator import testlib as spanner_emulator_testlib
from spanner_orm.tests import models

    self.assert_api_called(update, mock_transaction)

  @mock.patch('spanner_orm.table_apis.upsert')
  def test_save_batch_force_write_upserts(self, upsert):
    mock_transaction = mock.Mock()
    values = {'key': 'key', 'value_1': 'value'}
    not_persisted = models.SmallTestModel(values)
    models.SmallTestModel.save_batch(
        [not_persisted],
        force_write=True,
        transaction=mock_transaction,
    )
    self.assert_api_called(upsert, mock_transaction)

  @mock.patch('spanner_orm.table_apis.delete')
  def test_delete_batch_deletes(self, delete):
    mock_transaction = mock.Mock()
    values = {'key': 'key', 'value_1': 'value'}
    model = models.SmallTestModel(values)
    models.SmallTestModel.delete_batch([model], transaction=mock_transaction)

    delete.assert_called_once()
    (transaction, table, keyset), _ = delete.call_args
    self.assertEqual(transaction, mock_transaction)
    self.assertEqual(table, models.SmallTestModel.table)
    self.assertEqual(keyset.keys, [[model.key]])

  @mock.patch('spanner_orm.table_apis.delete')
  def test_delete_by_key_deletes(self, delete):
    mock_transaction = mock.Mock()

    models.SmallTestModel.delete_by_key(