class IndexTestModel(model.Model):
    __table__ = 'IndexTestModel'

    key = field.Field(field.String, primary_key=True)
    value = field.Field(field.String)

    value_index = index.Index(['value'])
Exemple #2
0
class OriginalSmallTestModelTable(spanner_orm.model.Model):
  """ORM Model with the original schema for the SmallTestModel table."""

  __table__ = 'SmallTestModel'
  key = field.Field(field.String, primary_key=True)
  value_1 = field.Field(field.String)
  value_2 = field.Field(field.String, nullable=True)
class ChildTestModel(model.Model):
    """Model class for testing interleaved tables."""

    __table__ = 'ChildTestModel'
    __interleaved__ = 'SmallTestModel'

    key = field.Field(field.String, primary_key=True)
    child_key = field.Field(field.String, primary_key=True)
class SmallTestModel(model.Model):
    """Model class used for testing."""

    __table__ = 'SmallTestModel'
    key = field.Field(field.String, primary_key=True)
    value_1 = field.Field(field.String)
    value_2 = field.Field(field.String, nullable=True)
    index_1 = index.Index(['value_1'])
Exemple #5
0
class MigrationStatus(model.Model):
    @classmethod
    def spanner_api(cls) -> api.SpannerAdminApi:
        return api.spanner_admin_api()

    __table__ = 'spanner_orm_migrations'
    id = typing.cast(str, field.Field(field.String, primary_key=True))
    migrated = typing.cast(bool, field.Field(field.Boolean))
    update_time = typing.cast(datetime.datetime, field.Field(field.Timestamp))
Exemple #6
0
class MigrationStatus(model.Model):
    @classmethod
    def spanner_api(cls) -> api.SpannerAdminApi:
        return api.spanner_admin_api()

    __table__ = "spanner_orm_migrations"
    id = field.Field(field.String, primary_key=True)
    migrated = field.Field(field.Boolean)
    update_time = field.Field(field.Timestamp)
Exemple #7
0
class TableSchema(schema.InformationSchema):
    """Model for interacting with Spanner column schema table."""

    __table__ = "information_schema.tables"
    table_catalog = field.Field(field.String, primary_key=True)
    table_schema = field.Field(field.String, primary_key=True)
    table_name = field.Field(field.String, primary_key=True)
    parent_table_name = field.Field(field.String, nullable=True)
    on_delete_action = field.Field(field.String, nullable=True)
Exemple #8
0
class IndexTestModel(model.Model):
    __table__ = "IndexTestModel"

    key = field.Field(field.String, primary_key=True)
    value = field.Field(field.String)

    value_idx = index.Index(["value"], name="value")
    value_idx2 = index.Index(
        ["value"], name="value_desc", column_ordering={"value": False}
    )
class RelationshipTestModel(model.Model):
    """Model class for testing relationships."""

    __table__ = 'RelationshipTestModel'
    parent_key = field.Field(field.String, primary_key=True)
    child_key = field.Field(field.String, primary_key=True)
    parent = relationship.Relationship(
        'spanner_orm.tests.models.SmallTestModel', {'parent_key': 'key'},
        single=True)
    parents = relationship.Relationship(
        'spanner_orm.tests.models.SmallTestModel', {'parent_key': 'key'})
Exemple #10
0
class SmallTestParentModel(model.Model):
    """Model class used for testing."""

    __table__ = "SmallTestParentModel"
    key = field.Field(field.String, primary_key=True)
    value_1 = field.Field(field.String)
    value_2 = field.Field(field.String, nullable=True)
    index_1 = index.Index(["value_1"])

    children = relationship.Relationship(
        "spanner_orm.tests.models.ChildTestModel", {"key": "key"}
    )
Exemple #11
0
class TableSchema(schema.InformationSchema):
    """Model for interacting with Spanner column schema table."""

    __table__ = 'information_schema.tables'
    table_catalog = typing.cast(str, field.Field(field.String,
                                                 primary_key=True))
    table_schema = typing.cast(str, field.Field(field.String,
                                                primary_key=True))
    table_name = typing.cast(str, field.Field(field.String, primary_key=True))
    parent_table_name = typing.cast(Optional[str],
                                    field.Field(field.String, nullable=True))
    on_delete_action = typing.cast(Optional[str],
                                   field.Field(field.String, nullable=True))
    def tables(cls) -> Dict[str, Dict[str, Any]]:
        """Compiles table information from column schema."""
        column_data = collections.defaultdict(dict)
        columns = column.ColumnSchema.where(
            None,
            condition.equal_to("table_catalog", ""),
            condition.equal_to("table_schema", ""),
        )
        for column_row in columns:
            new_field = field.Field(
                column_row.field_type,
                nullable=column_row.nullable,
                size=column_row.size,
            )
            new_field.name = column_row.column_name
            new_field.position = column_row.ordinal_position
            column_data[column_row.table_name][column_row.column_name] = new_field

        table_data = collections.defaultdict(dict)
        tables = table.TableSchema.where(
            None,
            condition.equal_to("table_catalog", ""),
            condition.equal_to("table_schema", ""),
        )
        for table_row in tables:
            name = table_row.table_name
            table_data[name]["parent_table"] = table_row.parent_table_name
            table_data[name]["fields"] = column_data[name]
        return table_data
Exemple #13
0
class RelationshipTestModel(model.Model):
    """Model class for testing relationships."""

    __table__ = "RelationshipTestModel"
    parent_key = field.Field(field.String, primary_key=True)
    child_key = field.Field(field.String, primary_key=True)
    parent = relationship.Relationship(
        "spanner_orm.tests.models.SmallTestModel", {"parent_key": "key"}, single=True
    )
    parents = relationship.Relationship(
        "spanner_orm.tests.models.SmallTestModel", {"parent_key": "key"}
    )
    fk_multicolumn = relationship.Relationship(
        "spanner_orm.tests.models.SmallTestModel",
        {"parent_key": "key", "parent_key2": "key2"},
    )
Exemple #14
0
class IndexColumnSchema(schema.InformationSchema):
    """Model for interacting with Spanner index column schema table."""

    __table__ = "information_schema.index_columns"
    table_catalog = field.Field(field.String, primary_key=True)
    table_schema = field.Field(field.String, primary_key=True)
    table_name = field.Field(field.String, primary_key=True)
    index_name = field.Field(field.String, primary_key=True)
    column_name = field.Field(field.String, primary_key=True)
    ordinal_position = field.Field(field.Integer, nullable=True)
    column_ordering = field.Field(field.String, nullable=True)
    is_nullable = field.Field(field.String)
    spanner_type = field.Field(field.String)
Exemple #15
0
class IndexSchema(schema.InformationSchema):
  """Model for interacting with Spanner index schema table."""

  __table__ = 'information_schema.indexes'
  table_catalog = field.Field(field.String, primary_key=True)
  table_schema = field.Field(field.String, primary_key=True)
  table_name = field.Field(field.String, primary_key=True)
  index_name = field.Field(field.String, primary_key=True)
  index_type = field.Field(field.String)
  parent_table_name = field.Field(field.String, nullable=True)
  is_unique = field.Field(field.Boolean)
  is_null_filtered = field.Field(field.Boolean)
  index_state = field.Field(field.String)
Exemple #16
0
class IndexSchema(schema.InformationSchema):
  """Model for interacting with Spanner index schema table."""

  __table__ = 'information_schema.indexes'
  table_catalog = typing.cast(str, field.Field(field.String, primary_key=True))
  table_schema = typing.cast(str, field.Field(field.String, primary_key=True))
  table_name = typing.cast(str, field.Field(field.String, primary_key=True))
  index_name = typing.cast(str, field.Field(field.String, primary_key=True))
  index_type = typing.cast(str, field.Field(field.String))
  parent_table_name = typing.cast(Optional[str],
                                  field.Field(field.String, nullable=True))
  is_unique = typing.cast(bool, field.Field(field.Boolean))
  is_null_filtered = typing.cast(bool, field.Field(field.Boolean))
  index_state = typing.cast(str, field.Field(field.String))
class OriginalForeignKeyTestModelTable(spanner_orm.model.Model):
    """ORM Model with the original schema for the ForeignKeyTestModel table."""

    __table__ = 'ForeignKeyTestModel'
    referencing_key_1 = field.Field(field.String, primary_key=True)
    referencing_key_2 = field.Field(field.String, primary_key=True)
    referencing_key_3 = field.Field(field.Integer, primary_key=True)
    self_referencing_key = field.Field(field.String, nullable=True)
    foreign_key_1 = foreign_key_relationship.ForeignKeyRelationship(
        'SmallTestModel', {'referencing_key_1': 'key'})
    foreign_key_2 = foreign_key_relationship.ForeignKeyRelationship(
        'UnittestModel',
        {
            'referencing_key_2': 'string',
            'referencing_key_3': 'int_'
        },
    )
    foreign_key_3 = foreign_key_relationship.ForeignKeyRelationship(
        'ForeignKeyTestModel', {'self_referencing_key': 'referencing_key_1'})
Exemple #18
0
class OriginalUnittestModelTable(spanner_orm.model.Model):
    """ORM Model with the original schema for the UnittestModel table."""

    __table__ = 'table'
    int_ = field.Field(field.Integer, primary_key=True)
    int_2 = field.Field(field.Integer, nullable=True)
    float_ = field.Field(field.Float, primary_key=True)
    float_2 = field.Field(field.Float, nullable=True)
    string = field.Field(field.String, primary_key=True)
    string_2 = field.Field(field.String, nullable=True)
    timestamp = field.Field(field.Timestamp)
    string_array = field.Field(field.StringArray, nullable=True)
    def test_create_table_foreign_keys_no_model(self, get_model):
        get_model.return_value = None
        test_update = update.CreateTable(
            table_name="RelationshipTestModel",
            primary_keys=["parent_key", "child_key"],
            fields={
                "parent_key":
                field.Field(field.String, primary_key=True, name="parent_key"),
                "child_key":
                field.Field(field.String, primary_key=True, name="child_key"),
            },
            relations={
                "parent":
                relationship.Relationship(
                    "spanner_orm.tests.models.SmallTestModel",
                    {"parent_key": "key"},
                    single=True,
                ),
                "parents":
                relationship.Relationship(
                    "spanner_orm.tests.models.SmallTestModel",
                    {"parent_key": "key"}),
                "fk_multicolumn":
                relationship.Relationship(
                    "spanner_orm.tests.models.SmallTestModel",
                    {
                        "parent_key": "key",
                        "parent_key2": "key2"
                    },
                ),
            },
        )
        test_update.validate()

        test_model_ddl = (
            "CREATE TABLE RelationshipTestModel ("
            "parent_key STRING(MAX) NOT NULL, "
            "child_key STRING(MAX) NOT NULL, "
            "CONSTRAINT parent FOREIGN KEY (parent_key) REFERENCES spanner_orm.tests.models.SmallTestModel (key), "
            "CONSTRAINT parents FOREIGN KEY (parent_key) REFERENCES spanner_orm.tests.models.SmallTestModel (key), "
            "CONSTRAINT fk_multicolumn FOREIGN KEY (parent_key, parent_key2) REFERENCES spanner_orm.tests.models.SmallTestModel (key, key2)) "
            "PRIMARY KEY (parent_key, child_key)")
        self.assertEqual(test_update.ddl(), test_model_ddl)
    def test_add_column(self, get_model):
        table_name = models.SmallTestModel.table
        get_model.return_value = models.SmallTestModel

        new_field = field.Field(field.String, nullable=True)
        test_update = update.AddColumn(table_name, 'bar', new_field)
        test_update.validate()
        self.assertEqual(
            test_update.ddl(),
            'ALTER TABLE {} ADD COLUMN bar STRING(MAX)'.format(table_name))
class UnittestModelWithoutSecondaryIndexes(model.Model):
    """Same as UnittestModel, but with no secondary indexes."""

    __table__ = 'table'
    int_ = field.Field(field.Integer, primary_key=True)
    int_2 = field.Field(field.Integer, nullable=True)
    float_ = field.Field(field.Float, primary_key=True)
    float_2 = field.Field(field.Float, nullable=True)
    string = field.Field(field.String, primary_key=True)
    string_2 = field.Field(field.String, nullable=True)
    timestamp = field.Field(field.Timestamp)
    string_array = field.Field(field.StringArray, nullable=True)
Exemple #22
0
class IndexColumnSchema(schema.InformationSchema):
    """Model for interacting with Spanner index column schema table."""

    __table__ = 'information_schema.index_columns'
    table_catalog = typing.cast(str, field.Field(field.String,
                                                 primary_key=True))
    table_schema = typing.cast(str, field.Field(field.String,
                                                primary_key=True))
    table_name = typing.cast(str, field.Field(field.String, primary_key=True))
    index_name = typing.cast(str, field.Field(field.String, primary_key=True))
    column_name = typing.cast(str, field.Field(field.String, primary_key=True))
    ordinal_position = typing.cast(Optional[int],
                                   field.Field(field.Integer, nullable=True))
    column_ordering = typing.cast(Optional[str],
                                  field.Field(field.String, nullable=True))
    is_nullable = typing.cast(str, field.Field(field.String))
    spanner_type = typing.cast(str, field.Field(field.String))
class ForeignKeyTestModel(model.Model):
    """Model class for testing foreign keys."""

    __table__ = 'ForeignKeyTestModel'
    referencing_key_1 = field.Field(field.String, primary_key=True)
    referencing_key_2 = field.Field(field.String, primary_key=True)
    referencing_key_3 = field.Field(field.Integer, primary_key=True)
    self_referencing_key = field.Field(field.String, nullable=True)
    foreign_key_1 = foreign_key_relationship.ForeignKeyRelationship(
        'spanner_orm.tests.models.SmallTestModel',
        {'referencing_key_1': 'key'})
    foreign_key_2 = foreign_key_relationship.ForeignKeyRelationship(
        'spanner_orm.tests.models.UnittestModel',
        {
            'referencing_key_2': 'string',
            'referencing_key_3': 'int_'
        },
    )
    foreign_key_3 = foreign_key_relationship.ForeignKeyRelationship(
        'spanner_orm.tests.models.ForeignKeyTestModel',
        {'self_referencing_key': 'referencing_key_1'})
class UnittestModel(model.Model):
    """Model class used for model testing."""

    __table__ = 'table'
    int_ = field.Field(field.Integer, primary_key=True)
    int_2 = field.Field(field.Integer, nullable=True)
    float_ = field.Field(field.Float, primary_key=True)
    float_2 = field.Field(field.Float, nullable=True)
    string = field.Field(field.String, primary_key=True)
    string_2 = field.Field(field.String, nullable=True)
    timestamp = field.Field(field.Timestamp)
    string_array = field.Field(field.StringArray, nullable=True)

    test_index = index.Index(['string_2'])
    def test_create_table_interleaved_no_model(self, get_model):
        get_model.return_value = None
        test_update = update.CreateTable(
            table_name="ChildTestModel",
            primary_keys=["key", "child_key"],
            fields={
                "key":
                field.Field(field.String, primary_key=True, name="key"),
                "child_key":
                field.Field(field.String, primary_key=True, name="child_key"),
            },
            interleaved=models.SmallTestModel,
        )
        test_update.validate()

        test_model_ddl = (
            "CREATE TABLE ChildTestModel ("
            "key STRING(MAX) NOT NULL, "
            "child_key STRING(MAX) NOT NULL) "
            "PRIMARY KEY (key, child_key), "
            "INTERLEAVE IN PARENT SmallTestModel ON DELETE CASCADE")
        self.assertEqual(test_update.ddl(), test_model_ddl)
Exemple #26
0
class ColumnSchema(schema.InformationSchema):
    """Model for interacting with Spanner column schema table."""

    __table__ = "information_schema.columns"
    table_catalog = field.Field(field.String, primary_key=True)
    table_schema = field.Field(field.String, primary_key=True)
    table_name = field.Field(field.String, primary_key=True)
    column_name = field.Field(field.String, primary_key=True)
    ordinal_position = field.Field(field.Integer)
    is_nullable = field.Field(field.String)
    spanner_type = field.Field(field.String)

    @property
    def nullable(self) -> bool:
        return self.is_nullable == "YES"

    @property
    def field_type(self) -> Type[field.FieldType]:
        for field_type in field.ALL_TYPES:
            if self.spanner_type == field_type.ddl():
                return field_type

        if bool(_string_pattern.match(self.spanner_type)):
            return field.String
        elif bool(_string_array_pattern.match(self.spanner_type)):
            return field.StringArray

        raise error.SpannerError(
            "No corresponding Type for {}".format(self.spanner_type)
        )

    @property
    def size(self) -> Union[None, int]:
        if bool(_string_pattern.match(self.spanner_type)) or bool(
            _string_array_pattern.match(self.spanner_type)
        ):
            # Extract digits from string (i.e. STRING(50) -> 50)
            return int("".join(filter(str.isdigit, self.spanner_type)))
        else:
            return None
Exemple #27
0
class ColumnSchema(schema.InformationSchema):
  """Model for interacting with Spanner column schema table."""

  __table__ = 'information_schema.columns'
  table_catalog = typing.cast(str, field.Field(field.String, primary_key=True))
  table_schema = typing.cast(str, field.Field(field.String, primary_key=True))
  table_name = typing.cast(str, field.Field(field.String, primary_key=True))
  column_name = typing.cast(str, field.Field(field.String, primary_key=True))
  ordinal_position = typing.cast(int, field.Field(field.Integer))
  is_nullable = typing.cast(str, field.Field(field.String))
  spanner_type = typing.cast(str, field.Field(field.String))

  def nullable(self) -> bool:
    return self.is_nullable == 'YES'

  def field_type(self) -> Type[field.FieldType]:
    for field_type in field.ALL_TYPES:
      if self.spanner_type == field_type.ddl():
        return field_type

    raise error.SpannerError('No corresponding Type for {}'.format(
        self.spanner_type))
Exemple #28
0
class ColumnSchema(schema.InformationSchema):
    """Model for interacting with Spanner column schema table."""

    __table__ = "information_schema.columns"
    table_catalog = field.Field(field.String, primary_key=True)
    table_schema = field.Field(field.String, primary_key=True)
    table_name = field.Field(field.String, primary_key=True)
    column_name = field.Field(field.String, primary_key=True)
    ordinal_position = field.Field(field.Integer)
    is_nullable = field.Field(field.String)
    spanner_type = field.Field(field.String)

    @property
    def nullable(self) -> bool:
        return self.is_nullable == "YES"

    @property
    def field_type(self) -> Type[field.FieldType]:
        for field_type in field.ALL_TYPES:
            if self.spanner_type == field_type.ddl():
                return field_type

        raise error.SpannerError("No corresponding Type for {}".format(
            self.spanner_type))
class InheritanceTestModel(SmallTestModel):
    """Model class used for testing model inheritance."""
    value_3 = field.Field(field.String, nullable=True)
    def test_create_table_no_model(self, get_model):
        get_model.return_value = None
        test_update = update.CreateTable(
            table_name="table",
            primary_keys=["int_", "float_", "string"],
            fields={
                "int_":
                field.Field(field.Integer, primary_key=True, name="int_"),
                "int_2":
                field.Field(field.Integer, nullable=True, name="int_2"),
                "float_":
                field.Field(field.Float, primary_key=True, name="float_"),
                "float_2":
                field.Field(field.Float, nullable=True, name="float_2"),
                "string":
                field.Field(field.String, primary_key=True, name="string"),
                "string_2":
                field.Field(field.String, nullable=True, name="string_2"),
                "string_3":
                field.Field(field.String,
                            nullable=True,
                            size=10,
                            name="string_3"),
                "timestamp":
                field.Field(field.Timestamp, name="timestamp"),
                "timestamp_2":
                field.Field(
                    field.Timestamp,
                    nullable=True,
                    allow_commit_timestamp=True,
                    name="timestamp_2",
                ),
                "date":
                field.Field(field.Date, nullable=True, name="date"),
                "bool_array":
                field.Field(field.BoolArray, nullable=True, name="bool_array"),
                "int_array":
                field.Field(field.IntegerArray,
                            nullable=True,
                            name="int_array"),
                "float_array":
                field.Field(field.FloatArray,
                            nullable=True,
                            name="float_array"),
                "date_array":
                field.Field(field.DateArray, nullable=True, name="date_array"),
                "string_array":
                field.Field(field.StringArray,
                            nullable=True,
                            name="string_array"),
                "string_array_2":
                field.Field(field.StringArray,
                            nullable=True,
                            size=50,
                            name="string_array_2"),
            },
        )
        test_update.validate()

        test_model_ddl = (
            "CREATE TABLE table (int_ INT64 NOT NULL, int_2 INT64,"
            " float_ FLOAT64 NOT NULL, float_2 FLOAT64,"
            " string STRING(MAX) NOT NULL, string_2 STRING(MAX),"
            " string_3 STRING(10),"
            " timestamp TIMESTAMP NOT NULL,"
            " timestamp_2 TIMESTAMP OPTIONS (allow_commit_timestamp=true),"
            " date DATE,"
            " bool_array ARRAY<BOOL>,"
            " int_array ARRAY<INT64>,"
            " float_array ARRAY<FLOAT64>,"
            " date_array ARRAY<DATE>,"
            " string_array ARRAY<STRING(MAX)>,"
            " string_array_2 ARRAY<STRING(50)>) PRIMARY KEY (int_, float_, string)"
        )
        self.assertEqual(test_update.ddl(), test_model_ddl)