As of January 1, 2020 this library no longer supports Python 2 on the latest released version.
Library versions released prior to that date will continue to be available. For more information please
visit Python 2 support on Google Cloud.
Source code for google.cloud.bigtable.column_family
# Copyright 2015 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""User friendly container for Google Cloud Bigtable Column Family."""
from google.cloud import _helpers
from google.cloud.bigtable_admin_v2.types import table as table_v2_pb2
from google.cloud.bigtable_admin_v2.types import (
bigtable_table_admin as table_admin_v2_pb2,
)
[docs]class GarbageCollectionRule(object):
"""Garbage collection rule for column families within a table.
Cells in the column family (within a table) fitting the rule will be
deleted during garbage collection.
.. note::
This class is a do-nothing base class for all GC rules.
.. note::
A string ``gc_expression`` can also be used with API requests, but
that value would be superceded by a ``gc_rule``. As a result, we
don't support that feature and instead support via native classes.
"""
[docs]class MaxVersionsGCRule(GarbageCollectionRule):
"""Garbage collection limiting the number of versions of a cell.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_create_family_gc_max_versions]
:end-before: [END bigtable_api_create_family_gc_max_versions]
:dedent: 4
:type max_num_versions: int
:param max_num_versions: The maximum number of versions
"""
def __init__(self, max_num_versions):
self.max_num_versions = max_num_versions
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return other.max_num_versions == self.max_num_versions
def __ne__(self, other):
return not self == other
[docs] def to_pb(self):
"""Converts the garbage collection rule to a protobuf.
:rtype: :class:`.table_v2_pb2.GcRule`
:returns: The converted current object.
"""
return table_v2_pb2.GcRule(max_num_versions=self.max_num_versions)
[docs]class MaxAgeGCRule(GarbageCollectionRule):
"""Garbage collection limiting the age of a cell.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_create_family_gc_max_age]
:end-before: [END bigtable_api_create_family_gc_max_age]
:dedent: 4
:type max_age: :class:`datetime.timedelta`
:param max_age: The maximum age allowed for a cell in the table.
"""
def __init__(self, max_age):
self.max_age = max_age
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return other.max_age == self.max_age
def __ne__(self, other):
return not self == other
[docs] def to_pb(self):
"""Converts the garbage collection rule to a protobuf.
:rtype: :class:`.table_v2_pb2.GcRule`
:returns: The converted current object.
"""
max_age = _helpers._timedelta_to_duration_pb(self.max_age)
return table_v2_pb2.GcRule(max_age=max_age)
[docs]class GCRuleUnion(GarbageCollectionRule):
"""Union of garbage collection rules.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_create_family_gc_union]
:end-before: [END bigtable_api_create_family_gc_union]
:dedent: 4
:type rules: list
:param rules: List of :class:`GarbageCollectionRule`.
"""
def __init__(self, rules):
self.rules = rules
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return other.rules == self.rules
def __ne__(self, other):
return not self == other
[docs] def to_pb(self):
"""Converts the union into a single GC rule as a protobuf.
:rtype: :class:`.table_v2_pb2.GcRule`
:returns: The converted current object.
"""
union = table_v2_pb2.GcRule.Union(rules=[rule.to_pb() for rule in self.rules])
return table_v2_pb2.GcRule(union=union)
[docs]class GCRuleIntersection(GarbageCollectionRule):
"""Intersection of garbage collection rules.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_create_family_gc_intersection]
:end-before: [END bigtable_api_create_family_gc_intersection]
:dedent: 4
:type rules: list
:param rules: List of :class:`GarbageCollectionRule`.
"""
def __init__(self, rules):
self.rules = rules
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return other.rules == self.rules
def __ne__(self, other):
return not self == other
[docs] def to_pb(self):
"""Converts the intersection into a single GC rule as a protobuf.
:rtype: :class:`.table_v2_pb2.GcRule`
:returns: The converted current object.
"""
intersection = table_v2_pb2.GcRule.Intersection(
rules=[rule.to_pb() for rule in self.rules]
)
return table_v2_pb2.GcRule(intersection=intersection)
[docs]class ColumnFamily(object):
"""Representation of a Google Cloud Bigtable Column Family.
We can use a :class:`ColumnFamily` to:
* :meth:`create` itself
* :meth:`update` itself
* :meth:`delete` itself
:type column_family_id: str
:param column_family_id: The ID of the column family. Must be of the
form ``[_a-zA-Z0-9][-_.a-zA-Z0-9]*``.
:type table: :class:`Table <google.cloud.bigtable.table.Table>`
:param table: The table that owns the column family.
:type gc_rule: :class:`GarbageCollectionRule`
:param gc_rule: (Optional) The garbage collection settings for this
column family.
"""
def __init__(self, column_family_id, table, gc_rule=None):
self.column_family_id = column_family_id
self._table = table
self.gc_rule = gc_rule
@property
def name(self):
"""Column family name used in requests.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_column_family_name]
:end-before: [END bigtable_api_column_family_name]
:dedent: 4
.. note::
This property will not change if ``column_family_id`` does not, but
the return value is not cached.
The Column family name is of the form
``"projects/../zones/../clusters/../tables/../columnFamilies/.."``
:rtype: str
:returns: The column family name.
"""
return self._table.name + "/columnFamilies/" + self.column_family_id
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
return (
other.column_family_id == self.column_family_id
and other._table == self._table
and other.gc_rule == self.gc_rule
)
def __ne__(self, other):
return not self == other
[docs] def to_pb(self):
"""Converts the column family to a protobuf.
:rtype: :class:`.table_v2_pb2.ColumnFamily`
:returns: The converted current object.
"""
if self.gc_rule is None:
return table_v2_pb2.ColumnFamily()
else:
return table_v2_pb2.ColumnFamily(gc_rule=self.gc_rule.to_pb())
[docs] def create(self):
"""Create this column family.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_create_column_family]
:end-before: [END bigtable_api_create_column_family]
:dedent: 4
"""
column_family = self.to_pb()
modification = table_admin_v2_pb2.ModifyColumnFamiliesRequest.Modification(
id=self.column_family_id, create=column_family
)
client = self._table._instance._client
# data it contains are the GC rule and the column family ID already
# stored on this instance.
client.table_admin_client.modify_column_families(
request={"name": self._table.name, "modifications": [modification]}
)
[docs] def update(self):
"""Update this column family.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_update_column_family]
:end-before: [END bigtable_api_update_column_family]
:dedent: 4
.. note::
Only the GC rule can be updated. By changing the column family ID,
you will simply be referring to a different column family.
"""
column_family = self.to_pb()
modification = table_admin_v2_pb2.ModifyColumnFamiliesRequest.Modification(
id=self.column_family_id, update=column_family
)
client = self._table._instance._client
# data it contains are the GC rule and the column family ID already
# stored on this instance.
client.table_admin_client.modify_column_families(
request={"name": self._table.name, "modifications": [modification]}
)
[docs] def delete(self):
"""Delete this column family.
For example:
.. literalinclude:: snippets_table.py
:start-after: [START bigtable_api_delete_column_family]
:end-before: [END bigtable_api_delete_column_family]
:dedent: 4
"""
modification = table_admin_v2_pb2.ModifyColumnFamiliesRequest.Modification(
id=self.column_family_id, drop=True
)
client = self._table._instance._client
# data it contains are the GC rule and the column family ID already
# stored on this instance.
client.table_admin_client.modify_column_families(
request={"name": self._table.name, "modifications": [modification]}
)
def _gc_rule_from_pb(gc_rule_pb):
"""Convert a protobuf GC rule to a native object.
:type gc_rule_pb: :class:`.table_v2_pb2.GcRule`
:param gc_rule_pb: The GC rule to convert.
:rtype: :class:`GarbageCollectionRule` or :data:`NoneType <types.NoneType>`
:returns: An instance of one of the native rules defined
in :module:`column_family` or :data:`None` if no values were
set on the protobuf passed in.
:raises: :class:`ValueError <exceptions.ValueError>` if the rule name
is unexpected.
"""
rule_name = gc_rule_pb._pb.WhichOneof("rule")
if rule_name is None:
return None
if rule_name == "max_num_versions":
return MaxVersionsGCRule(gc_rule_pb.max_num_versions)
elif rule_name == "max_age":
return MaxAgeGCRule(gc_rule_pb.max_age)
elif rule_name == "union":
return GCRuleUnion([_gc_rule_from_pb(rule) for rule in gc_rule_pb.union.rules])
elif rule_name == "intersection":
rules = [_gc_rule_from_pb(rule) for rule in gc_rule_pb.intersection.rules]
return GCRuleIntersection(rules)
else:
raise ValueError("Unexpected rule name", rule_name)