Ejemplo n.º 1
0
    def models(cls) -> Dict[str, Type[model.Model]]:
        """Constructs model classes from Spanner table schema."""
        tables = cls.tables()
        indexes = cls.indexes()
        models = {}

        for table_name, table_data in tables.items():
            primary_index = indexes[table_name][index.Index.PRIMARY_INDEX]
            primary_keys = set(primary_index.columns)
            klass = model.ModelMetaclass(
                cls._class_name_from_table(table_name), (model.Model,), {}
            )
            for model_field in table_data["fields"].values():
                model_field._primary_key = (
                    model_field.name in primary_keys
                )  # pylint: disable=protected-access

            klass.meta = metadata.ModelMetadata(
                table=table_name,
                fields=table_data["fields"],
                interleaved=cls._class_name_from_table(table_data["parent_table"]),
                indexes=indexes[table_name],
                model_class=klass,
            )
            klass.meta.finalize(reregister_model=True)
            models[table_name] = klass

        return models
Ejemplo n.º 2
0
    def __new__(mcs, name: str, bases: Any, attrs: Dict[str, Any],
                **kwargs: Any):
        parents = [base for base in bases if isinstance(base, ModelMetaclass)]
        if not parents:
            return super().__new__(mcs, name, bases, attrs, **kwargs)

        model_metadata = metadata.ModelMetadata()
        for parent in parents:
            if 'meta' in vars(parent):
                model_metadata.add_metadata(parent.meta)

        non_model_attrs = {}
        for key, value in attrs.items():
            if key == '__table__':
                model_metadata.table = value
            elif key == '__interleaved__':
                model_metadata.interleaved = value
            if isinstance(value, field.Field):
                model_metadata.add_field(key, value)
            elif isinstance(value, index.Index):
                model_metadata.add_index(key, value)
            elif isinstance(value, relationship.Relationship):
                model_metadata.add_relation(key, value)
            else:
                non_model_attrs[key] = value

        cls = super().__new__(mcs, name, bases, non_model_attrs, **kwargs)

        # If a table is set, this class represents a complete model, so finalize
        # the metadata
        if model_metadata.table:
            model_metadata.model_class = cls
            model_metadata.finalize()
        cls.meta = model_metadata
        return cls