Epiphany Queries

Python Epiphany collection classes can be queried in a way that is reminiscent of SQL WHERE clauses, except with the full expressive power of Python. Let’s create a deities collection class and a corresponding deity entity class to set up a demonstration.

class deities(entities):

class deity(entity):
    def __init__(self, name, gender):
        self.name = name
        self.gender = gender

Here, deities inherits from entities making it a collection class. deity objects will obviously be appended to this collection class. Each deity object will store the deities name and gender.

Let’s start by using our classes to build up a pantheon of the major Greek gods and goddesses.

pantheon = deities()
pantheon  +=  deity('Aphrodite',   'female')
pantheon  +=  deity('Apollo',      'male')
pantheon  +=  deity('Ares',        'male')
pantheon  +=  deity('Artemis',     'female')
pantheon  +=  deity('Athena',      'female')
pantheon  +=  deity('Demeter',     'female')
pantheon  +=  deity('Hades',       'male')
pantheon  +=  deity('Hephaestus',  'male')
pantheon  +=  deity('Hera',        'female')
pantheon  +=  deity('Hermes',      'male')
pantheon  +=  deity('Hestia',      'female')
pantheon  +=  deity('Poseidon',    'male')
pantheon  +=  deity('Zeus',        'male')

Now, using the pantheon collection object, lets create gods and goddesses collections by querying the pantheon collection.

gods = pantheon.where(lambda x: x.gender == 'male')
goddesses = pantheon.where(lambda x: x.gender == 'female')

assert isinstance(gods, entities)
assert isinstance(goddesses, entities)

assert gods.count == 7
assert goddesses.count == 6

The first line uses the where method to collect all the deities that are male. The second line does the same for female deities. A lambda object is used as the query, though any Python callable, such as a function, could be used. Lambdas have the advantage of being terse.

Later we can assert that the where method returns a generic entities class . Ideally, where would have created and returned a deities class in this example. However, that feature hasn’t been implemented yet.

Finally, we make use of the queries to observe that there are 7 male deities and 6 female deities in our original pantheon collection.

In the above queries, only one property, gender, was tested for equality. However, we can make the test as expressive as any Python expression can be. Let’s say we want to see how many male deities are in our pantheon collection whose name starts with the letter ‘A’.

gods = pantheon.where(lambda x: x.name[0] == 'A' and x.gender == 'male')
assert gods.count == 2
assert gods[0].name == 'Apollo'
assert gods[1].name == 'Ares'

Here we see it’s no problem to use Python’s string indexing as well as the and operator to create a slightly more complex query. Of course, very complicated queries with complex nested Boolean expressions can be used as well. We can see that two deities are returned: the first being ‘Apollo’ and the second being ‘Ares’.

Leave a Reply

Your email address will not be published. Required fields are marked *