Skip to content

[Tables] Updating EntityProperty #18177

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 4, 2021
Merged
4 changes: 4 additions & 0 deletions sdk/tables/azure-data-tables/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@
* Removed the `TableClient.create_batch` method along with the `TableBatchOperations` object. The transactional batching is now supported via a simple Python list of tuples.
* `TableClient.send_batch` has been renamed to `TableClient.submit_transaction`.
* Removed `BatchTransactionResult` object in favor of returning an iterable of batched entities with returned metadata.
* Removed Batching context-manager behavior
* Changed optional `value` and `type` arguments of `EntityProperty` to required.
* Renamed `EntityProperty.type` to `EntityProperty.edm_type`.
* `BatchErrorException` has been renamed to `TableTransactionError`.
* `EntityProperty` is now a tuple.
* Removed `date` and `api_version` from the `TableItem` class.

**Fixes**
Expand Down
10 changes: 7 additions & 3 deletions sdk/tables/azure-data-tables/azure/data/tables/_deserialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,17 @@ def _deserialize_table_creation(response, _, headers):


def _from_entity_binary(value):
return EntityProperty(_decode_base64_to_bytes(value))
# type: (str) -> EntityProperty
return EntityProperty(_decode_base64_to_bytes(value), EdmType.BINARY)


def _from_entity_int32(value):
return EntityProperty(int(value))
# type: (str) -> EntityProperty
return EntityProperty(int(value), EdmType.INT32)


def _from_entity_int64(value):
# type: (str) -> EntityProperty
return EntityProperty(int(value), EdmType.INT64)


Expand Down Expand Up @@ -125,7 +128,8 @@ def _from_entity_guid(value):


def _from_entity_str(value):
return EntityProperty(value=value, type=EdmType.STRING)
# type: (str) -> EntityProperty
return EntityProperty(value, EdmType.STRING)


_EDM_TYPES = [
Expand Down
87 changes: 20 additions & 67 deletions sdk/tables/azure-data-tables/azure/data/tables/_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,9 @@
# license information.
# --------------------------------------------------------------------------
from enum import Enum
from datetime import datetime
from uuid import UUID
import six
from typing import Any, Dict, Union, NamedTuple

from ._error import _ERROR_ATTRIBUTE_MISSING, _ERROR_VALUE_TOO_LARGE
from ._error import _ERROR_ATTRIBUTE_MISSING


class TableEntity(dict):
Expand Down Expand Up @@ -68,69 +66,6 @@ def __dir__(self):
return dir({}) + list(self.keys())


class EntityProperty(object):
"""
An entity property. Used to explicitly set :class:`~EdmType` when necessary.

Values which require explicit typing are GUID, INT64, and BINARY. Other EdmTypes
may be explicitly create as EntityProperty objects but need not be. For example,
the below with both create STRING typed properties on the entity::
entity = TableEntity()
entity.a = 'b'
entity.x = EntityProperty('y', EdmType.STRING)
"""

def __init__(
self,
value=None, # type: Any
type=None, # type: Union[str,EdmType] pylint: disable=redefined-builtin
):
"""
Represents an Azure Table. Returned by list_tables.

:param type: The type of the property.
:type type: str or EdmType
:param Any value: The value of the property.
"""
self.value = value
if type is not None:
self.type = type
elif isinstance(value, six.text_type):
try:
self.value = UUID(value)
self.type = EdmType.GUID
except ValueError:
self.type = EdmType.STRING
elif isinstance(value, six.binary_type):
self.type = EdmType.BINARY
elif isinstance(value, bool):
self.type = EdmType.BOOLEAN
elif isinstance(value, six.integer_types):
if value.bit_length() <= 32:
self.type = EdmType.INT32
else:
raise TypeError(
_ERROR_VALUE_TOO_LARGE.format(str(value), EdmType.INT32)
)
elif isinstance(value, datetime):
self.type = EdmType.DATETIME
elif isinstance(value, float):
self.type = EdmType.DOUBLE
else:
raise ValueError(
"""Type of {} could not be inferred. Acceptable types are bytes, int, uuid.UUID,
datetime, string, int32, int64, float, and boolean. Refer to
azure.data.tables.EdmType for more information.
""".format(
value
)
)

def __eq__(self, other):
# type: (TableEntity) -> bool
return self.value == other.value and self.type == other.type


class EdmType(str, Enum):
"""
Used by :class:`~.EntityProperty` to represent the type of the entity property
Expand Down Expand Up @@ -160,3 +95,21 @@ class EdmType(str, Enum):

BOOLEAN = "Edm.Boolean"
""" Represents a boolean. This type will be inferred for Python bools. """


EntityProperty = NamedTuple("EntityProperty", [("value", Any), ("edm_type", Union[str, EdmType])])
"""
An entity property. Used to explicitly set :class:`~EdmType` when necessary.

Values which require explicit typing are GUID, INT64, and BINARY. Other EdmTypes
may be explicitly create as EntityProperty objects but need not be. For example,
the below with both create STRING typed properties on the entity::
entity = TableEntity()
entity.a = 'b'
entity.x = EntityProperty('y', EdmType.STRING)

:param value:
:type value: Any
:param edm_type: Type of the value
:type edm_type: str or :class:`~azure.data.tables.EdmType`
"""
10 changes: 4 additions & 6 deletions sdk/tables/azure-data-tables/azure/data/tables/_serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from azure.core import MatchConditions
from azure.core.exceptions import raise_with_traceback

from ._entity import EdmType, EntityProperty
from ._entity import EdmType
from ._common_conversion import _encode_base64, _to_utc_datetime
from ._error import _ERROR_VALUE_TOO_LARGE, _ERROR_TYPE_NOT_SUPPORTED

Expand Down Expand Up @@ -225,11 +225,9 @@ def _add_entity_properties(source):
mtype, value = conv(value)
elif isinstance(value, datetime):
mtype, value = _to_entity_datetime(value)
elif isinstance(value, EntityProperty):
conv = _EDM_TO_ENTITY_CONVERSIONS.get(value.type)
if conv is None:
raise TypeError(_ERROR_TYPE_NOT_SUPPORTED.format(value.type))
mtype, value = conv(value.value)
elif isinstance(value, tuple):
conv = _EDM_TO_ENTITY_CONVERSIONS.get(value[1])
mtype, value = conv(value[0])
else:
conv = _PYTHON_TO_ENTITY_CONVERSIONS.get(type(value))
if conv is None and value is not None:
Expand Down
Loading