Example #1
0
  def commit(self):
    """Commits the transaction.

    This is called automatically upon exiting a with statement,
    however it can be called explicitly
    if you don't want to use a context manager.

    This method has necessary side-effects:

    - Sets the current connection's transaction reference to None.
    - Sets the current transaction's ID to None.
    - Updates paths for any keys that needed an automatically generated ID.
    """
    # It's possible that they called commit() already, in which case
    # we shouldn't do any committing of our own.
    if self.connection().transaction():
      result = self.connection().commit(self.dataset().id(), self.mutation())

      # For any of the auto-id entities, make sure we update their keys.
      for i, entity in enumerate(self._auto_id_entities):
        key_pb = result.insert_auto_id_key[i]
        key = Key.from_protobuf(key_pb)
        entity.key(entity.key().path(key.path()))

    # Tell the connection that the transaction is over.
    self.connection().transaction(None)

    # Clear our own ID in case this gets accidentally reused.
    self._id = None
Example #2
0
  def from_protobuf(cls, pb):
    entity = cls(key=Key.from_protobuf(pb.key))

    for property_pb in pb.property:
      value = helpers.get_value_from_protobuf(property_pb)
      entity[property_pb.name] = value

    return entity
Example #3
0
  def from_protobuf(cls, pb, dataset=None):
    """Factory method for creating an entity based on a protobuf.

    The protobuf should be one returned from the Cloud Datastore Protobuf API.

    :type key: :class:`gclouddatastore.datastore_v1_pb2.Entity`
    :param key: The Protobuf representing the entity.

    :returns: The :class:`Entity` derived from the :class:`gclouddatastore.datastore_v1_pb2.Entity`.
    """

    # This is here to avoid circular imports.
    from gclouddatastore import helpers

    key = Key.from_protobuf(pb.key, dataset=dataset)
    entity = cls.from_key(key)

    for property_pb in pb.property:
      value = helpers.get_value_from_protobuf(property_pb)
      entity[property_pb.name] = value

    return entity
Example #4
0
def get_value_from_protobuf(pb):
  """Given a protobuf for a Property, get the correct value.

  The Cloud Datastore Protobuf API returns a Property Protobuf
  which has one value set and the rest blank.
  This method retrieves the the one value provided.

  Some work is done to coerce the return value into a more useful type
  (particularly in the case of a timestamp value, or a key value).

  :type pb: :class:`gclouddatastore.datastore_v1_pb2.Property`
  :param pb: The Property Protobuf.

  :returns: The value provided by the Protobuf.
  """

  if pb.value.HasField('timestamp_microseconds_value'):
    timestamp = pb.value.timestamp_microseconds_value / 1e6
    return datetime.fromtimestamp(timestamp).replace(tzinfo=pytz.utc)

  elif pb.value.HasField('key_value'):
    return Key.from_protobuf(pb.value.key_value)

  elif pb.value.HasField('boolean_value'):
    return pb.value.boolean_value

  elif pb.value.HasField('double_value'):
    return pb.value.double_value

  elif pb.value.HasField('integer_value'):
    return pb.value.integer_value

  elif pb.value.HasField('string_value'):
    return pb.value.string_value

  else:
    # TODO(jjg): Should we raise a ValueError here?
    return None
Example #5
0
  def save(self):
    """Save the entity in the Cloud Datastore.

    :rtype: :class:`gclouddatastore.entity.Entity`
    :returns: The entity with a possibly updated Key.
    """
    key_pb = self.dataset().connection().save_entity(
        dataset_id=self.dataset().id(), key_pb=self.key().to_protobuf(),
        properties=dict(self))

    # If we are in a transaction and the current entity needs an
    # automatically assigned ID, tell the transaction where to put that.
    transaction = self.dataset().connection().transaction()
    if transaction and self.key().is_partial():
      transaction.add_auto_id_entity(self)

    if isinstance(key_pb, datastore_pb.Key):
      updated_key = Key.from_protobuf(key_pb)
      # Update the path (which may have been altered).
      key = self.key().path(updated_key.path())
      self.key(key)

    return self
Example #6
0
 def save(self):
   key = self._connection.save_entity(self)
   self.key(Key.from_protobuf(key))
   return self