Package: smartninja-nosql
SmartNinja NoSQLAboutSmartNinja NoSQL is a simple ODM tool which helps youswitchbetween these NoSQL database systems:TinyDB,Datastore,Firestore,MongoDBandCosmos DB(via MongoDB API).TinyDB is used for localhost development. The advantage is that it saves you time configuring a Firestore, Datastore, MonogDB or Cosmos emulator on localhost.When you deploy your web app to Google App Engine, Heroku or Azure App Service, the ODM figures out the new environment (through env variables) and switches the database accordingly.Bear in mind that this is a simple ODM meant to be used at theSmartNinja coursesfor learning purposes. So not all
features of these NoSQL databases are covered, only the basic ones.InstallationAdd this dependency in yourrequirements.txt:smartninja-nosqlMake sure to install it locally using this command:pip install -r requirements.txtOther dependenciesSmartNinja NoSQL has two mandatory dependencies:tinydbandtinydb_serialization. These two help SmartNinja NoSQL use a TinyDB database for localhost development.DatastoreGoogle Cloud Datastore dependency inrequirements.txt:google-cloud-datastoreFirestoreGoogle Cloud Firestore dependency inrequirements.txt:google-cloud-firestoreMongoDB & Cosmos DBTo use MongoDB on Heroku or Cosmos DB on Azure App Service, you'll need to add the following library in yourrequirements.txtfile:pymongoHerokuIf you'll use MongoDB on Heroku, make sure to choose themLab MongoDBadd-on.Environment variablesThe environment variables should already be automatically created, but still make sure they (still) have the correct names.Heroku:MONGODB_URI(shows up when you add the mLab MongoDB add-on)DYNO(standard Heroku env var, not visible on the dashboard)Azure:APPSETTING_WEBSITE_SITE_NAME(env vars that start with "APPSETTING_" are Azure's standard env vars. Not visible on the dashboard)APPSETTING_MONGOURL(shows up when you enable Cosmos DB with the Mongo API)Google Cloud:GAE_APPLICATION(standard GAE env var)Important: Datastore environment variableIf you'd like to use Datastore on GAE, you must add this piece of code into yourapp.yamlfile:env_variables:
  GAE_DATABASE: "datastore"If you'd like to use Firestore instead, enter "firestore" or don't have this env. variable at all (Firestore is default).UsageCreating classesThis is the simplest way to create classes that use SmartNinja NoSQL:fromsmartninja_nosql.odmimportModelclassUser(Model):passWhen you initialize a new object, you can add as many attributes as you want (no need to define them in the User model):user=User(first_name="Matt",last_name="Ramuta",age=31,human=True)But usually you'd want to specify at least some mandatory fields in a class:classUser(Model):def__init__(self,first_name,last_name,age,human=True,**kwargs):self.first_name=first_nameself.last_name=last_nameself.age=ageself.human=humanself.created=datetime.datetime.now()super().__init__(**kwargs)As you can see,first_name,last_nameandageare mandatory fields, whilehumanis optional and has a default value ofTrue.Thecreatedfield is automatically assigned a value ofdatetime.datetime.now().Important: Thesuper().__init__(**kwargs)line must be the last one in the__init__method! Also**kwargsmust be added as a function parameter.Custom class methodsYour classes will inherit the following methods from the Model class:create()edit()get_collection()delete()get()fetch()fetch_one()But you can of course create your own custom methods. Example:classUser(Model):def__init__(self,first_name,last_name,age,human=True,**kwargs):self.first_name=first_nameself.last_name=last_nameself.age=ageself.human=humanself.created=datetime.datetime.now()super().__init__(**kwargs)defget_full_name(self):return"{0}{1}".format(self.first_name,self.last_name)Creating new objectsuser=User(first_name="Matt",last_name="Ramuta",age=31)user.create()print(user.id)As you can see, creating an object needs two things: initializing an object and saving it into a database with thecreate()method. If you don't call this method, the object will not be saved into a database.Thecreate()method returns back theobject ID, which isautomaticallycreated by the database. The ID is also stored in the object itself.Get one object from the databaseYou can get an object out of the database if you know itsid:# Add new object to the database:user=User(first_name="Matt",last_name="Ramuta",age=31)user_id=user.create()# Get the User object from the databasenew_obj=User.get(obj_id=user_id)You can also find an object based on some other field using thefetch_one()method:# search on one fieldone_user=User.fetch_one(query=["first_name","==","Matt"])# search on many fieldsquery_age=["age",">",30]query_human=["human","==",True]one_user=User.fetch_one(query_age=query_age,query_human=query_human)Edit an objectYou need to pass the object id and the fields you want to edit:User.edit(obj_id=user_id,first_name="John",age=25)Delete an objectCall thedelete()method and pass the object id:User.delete(obj_id=user_id)Query the database and fetch objects that match the queryYou can specifyone query:query=["first_name","==","Matt"]users=User.fetch(query=query)print(users[0].first_name)print(users[0].id)What you'll get is a list of objects that match the query.You can also havemultiple queries:query_age=["age",">",30]query_human=["human","==",True]users=User.fetch(query_age=query_age,query_human=query_human)But be aware, that some databases (like Firestore) might require that you create an index for these composite queries.Important:This query structure must be followed (as shown in examples):["field", "operator", value]. So thefield nameand
theoperatormust be written in quotes.The "not equal" queries ("!=") are not allowed, because Firestore does not support them (although TinyDB and Cosmos
DB do).Enable a TinyDB test database (for localhost testing)Create an environment variable namedTESTING:import os
os.environ["TESTING"] = "1"This will create a test TinyDB database:test_db.json.How the right database is determinedSmartNinja NoSQL automatically determines which database to use. If the environment has theGAE_APPLICATIONvariable, then
the selected database isFirestore(unless you added theGAE_DATABASE: "datastore"environment variable inapp.yaml).If SmartNinja NoSQL finds aAPPSETTING_WEBSITE_SITE_NAMEit assumes the environment isAzure, so the selected database isCosmos DB. But ifnoneof these two environment variables is found, the
selected database isTinyDB.TODOTestsContinuous integration"order" supportautomatic composite index generator for Cloud Datastore (index.yaml)