简体   繁体   中英

NDB Repeated Property List with 'None' Values

I need a Property type that can set and get True, False and None values to NDB using the Python interface. For single Property attributes, this is fairly easy to do.

For repeated Property attributes (repeated=True), however, it seems impossible to set a list item to None. Whichever approach I've tried, the NDB library raises exceptions.

One attempt looks like this:

class LOGICAL(ndb.GenericProperty):

  def _set_value(self, entity, value):
    if isinstance(value, (list, tuple, set, frozenset)):
        for i, val in enumerate(value):
            if isinstance(val, str):
                if val.lower() in ('unknown', 'none'):
                    value[i] = None
    if isinstance(value, str):
        if value.lower() in ('unknown', 'none'):
            value = None
    ndb.Property._set_value(self, entity, value)

  def _validate(self, value):
    if isinstance(value, str):
        if value.lower() == 'true':
            return True
        if value.lower() == 'false':
            return False
        raise AssertionError('LOGICAL must be one of "true","false","unknown","none" or'
                             'True, False, None.')
    if value is not None:
        assert isinstance(value, bool)

This code runs fine for single LOGICAL properties, but as soon as I want to assign a list such as [True,'false',None], None will be rejected. I get the following warnings from the 'machine' in the background and a long, long stack trace.

WARNING:root:initial generator _put_tasklet(context.py:270) raised AssertionError()
WARNING:root:suspended generator put(context.py:748) raised AssertionError()

Please let me know if my task is an impossible one, or which approach to take.

_validate does not correctly handle the cases for "unknown" and "none":

        if value.lower() in ('unknown', 'none'):
            return None

Then, at the very end of the function:

    return value

So the resulting function is:

def _validate(self, value):
    if isinstance(value, str):
        if value.lower() == 'true':
            return True
        if value.lower() == 'false':
            return False
        if value.lower() in ('unknown', 'none'):    # Add these two lines
            return None
        raise AssertionError('LOGICAL must be one of "true","false","unknown","none" or'
                             'True, False, None.')
    if value is not None:
        assert isinstance(value, bool)
    return value

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM