Datastorm entities
Basic Entity definition
An entity is a mapping between Google's Datastore and Python objects.
from datastorm import Datastorm
from datastorm import fields
datastorm = Datastorm("test-project")
class FruitEntity(datastorm.DSEntity):
__kind__ = 'Fruit' # Entity's name in Datastore
color = fields.StringField()
weight = fields.IntField()
Base attributes
Base attributes are fields that the instances of your entity should have.
The tree that doesn't bend breaks. Be flexible, be like bamboo.
See, Datastore is a schemaless database. For that reason, two instances of your entity could have different attributes, and without no rules your shiny Python code could turn into a bug-nest.
However, we know pretty damn well bamboo trees have structure! You ain't lying to us Bruce Lee!
Datastorm takes a bamboo-style approach and let's you define attributes that almost all entity instances will have.
Although Datastorm doesn't really limits you in how you define attributes on the fly, It isn't really a good idea to do so. The more you define your entities' structure, the less bugs you'll have.
Entity Creation
Creating a Datastorm entity and saving it to your Datastore database is reeaaaaaally simple.
Using the FruitEntity
we created earlier:
strawberry = FruitEntity("strawberry", color="red", weight=3, is_smol=True) # "strawberry" is the datastore key
strawberry.save()
strawberry.weight = 1 # Strawberries are small ok?
strawberry.save()
And that's how you create and save an entity! Really simple right?
See, the only "pain" you must live with is providing the Datastore key in the constructor. That aside, you can pass all attributes you want in the constructor and Datastorm will treat them like Datastore fields automatically.
Yes, even if you pass an attribute that doesn't exist.
Even though I've told you not to declare attributes on the fly, If you are going to do naughty things, at least do it in a proper way:
strawberry.set('berry', True, field=fields.BooleanField())
Entity deletion
Deleting an entity's instance is even easier than creating it:
strawberry.delete()
And that's it.
Entity sync
Imagine you create an entity's instance in your code. And you are pretty damn sure this particular instance also exists in Datastore.
Instead of making a query or a get
, you could directly sync it and have it updated anytime you want:
orange = FruitEntity("orange")
orange.sync()
print(orange.color) # "orange"
sync()
will fetch your Datastore entity and will map everything in your Datastorm instance for you.
The only thing you must be careful with is that this will override all the properties your Datastorm entity instance shares with its Datastore counterpart.
Base filters
Imagine that for some reason (my reason was comfort but each their own) you want to declare two Datastorm entities that refer to the same Datastore entity kind:
class RedFruitEntity(datastorm.DSEntity):
__kind__ = 'Fruit'
is_strawberry = fields.BooleanField(default=False)
Following a little naming logic, you would expect your RedFruitEntity
instances to have color='red'
, but right now this isn't the case.
Worry no more, I have the solution!
from datastorm.filter import Filter
class RedFruitEntity(datastorm.DSEntity):
__kind__ = 'Fruit'
__base_filters_ = [Filter('color', '=', 'red')]
is_strawberry = fields.BooleanField(default=False)
In your entity definition you could add a list of filters that will be taken into consideration every time you perform a query against Datastore. In this example, every instance will have the color
attribute to red
.
Getting the Datastore Entity object
There'll be times when this awesome ODM we call Datastorm could fall short for a certain usecase of yours. Maybe you felt kinky and tried excluding some attributes from the index?
Lucky for you, kinky programmer, there's a easy way to translate a Datastorm entity into a Datastore entity:
strawberry.get_datastore_entity()
Huh, it was that easy. Who would've known!