Package: datastore-entity
Datastore EntityDatastore Entity package provides a simple ORM-like (think SQL-Alchemy) interface toGoogle CloudNoSQLDatastore(Firestore in Datastore mode)."Google Cloud Firestore in Datastore mode is a NoSQL document database built for automatic scaling, high performance, and ease of application development."Datastore Entity allows you to represent your entities using Python classes.
You can then use familiar ORM patterns with popular packages like WTForms(eg.form.populate_obj(model)) or
Flask-Login(ieUsermodel for authentication), to create, read, update and delete entities.DocumentationDatastore Entity documentationQuick StartAs always, to connect to a Google Cloud Platform service from your local machine, you need to set up a service account key.
Use the environment variableGOOGLE_APPLICATION_CREDENTIALSto point to the JSON fileexportGOOGLE_APPLICATION_CREDENTIALS="/code/auth/datastore-service-account.json"See below for another method of connecting by manually specifying the location of the service account JSON file.InstallationInstall the package using pippipinstalldatastore-entityUsage ExamplesSome examples ...Create A Model Classfromdatastore_entityimportDatastoreEntity,EntityValueclassUser(DatastoreEntity):# specify a default value of 'None'username=EntityValue(None)# or provide no argument to imply 'None'password=EntityValue()# default value of 1active=EntityValue(1)date_created=EntityValue(datetime.datetime.utcnow())# specify the name of the entity kind.# This is REQUIRED. Raises ValueError otherwise__kind__="user"# optionally add properties to exclude from datastore indexes__exclude_from_index__=['password']# call the super class heredef__init__(self,**kwargs):super(User,self).__init__(**kwargs)# other useful methods go here...Connecting To Datastore# connect to the default datastore namespace.user=User()# After connecting, you can retrieve an entity as an object# or populate attributes and save the entity#connect to the 'custom' datastore namespaceuser=User(namespace='custom')# connect using a service account JSON key (as opposed to using# the environment variable GOOGLE_APPLICATION_CREDENTIALS)user=User(service_account_json_path='path/to/service/account.json')Persist an entity# set object attributeuser.username='komla'# save or update entity to datastoreuser.save()# save an entity with custom ID/Nameuser.save(id='komla')Generate datastore key# Create a key by specifing a parent and descendant(s)key_path=['Client','foo','Department','bar']ancestor_key=user.generate_key(key_path)# then save an entity as a descendant of a parent entityuser.save(parent_or_ancestor=ancestor_key)Retrieve an entity as an object# specify property name and value. See the Tips sections below!user=User().get_obj('username','komla')# the 'key' attribute is the entity's datastore keyentity_key=user.key# get the entity's id or namename=user.key.id_or_name# get the entity's parent's keyparent_key=user.key.parentTipsUsing A Base ModelYou can use a class to represent common properties/columns, then inherit it for your modelsclassBaseModel(DatastoreEntity):date_created=EntityValue(datetime.datetime.utcnow())created_by=EntityValue('Admin')updated_by=EntityValue(None)classUser(BaseModel):username=EntityValue(None)password=EntityValue()email=EntityValue(None)# ...Retrieving Entity As ObjectOften, you'll have a property/column you use to fetch an entity (eg, username or email)
Instead of always specifying the property/column AND value using the providedget_obj()method,
you can simplify this by wrapping your own method for your model aroundget_obj():defget(self,value):returnself.get_obj('username',value)Then you can grab your entity/object withuser = User().get('komla')TestingTo initialize your model without connecting to datastore(eg. for the purposes of testing),
pass in theconnargument asFalseuser=User(conn=False)NotesThere might be operations you want to perform that are not available via the interface provided.
To get a direct access to Datastore connection client, use theget_client()method.datastore_client=user.get_client()# ... proceed with operation