Database Cheat Sheet
What you can do with databases:
- Create: Query/Read
- Read: Put information into it/write
- Update: Delete from the database
- Delete: Edit/Update Data
Questions to ask yourself:
- What data do I need to represent?
- What do I call it?
- What properties do I call it?
- How does it relate to other models? With a key property in a…
- One to Many relationship
- Many to Many relationship
Creating and Reading a Request
Three ways a user can create a request:
- Click on a link
- Submit a form
- Type into the url
Three things are handlers doing:
- Read the request: self.request.get(key) getting the key from the request
- Logic that interacts with the database
- Send a response: self.response.write(render(template)) render with data.
Reading the Request:
If I put this in the url
/detail?key=
I read the request by
self.request.get(key)
The key on the left is used to get the value on the right.
In the Python handler:
How do we get the key out of the handler out of the request?
urlsafe_key=self.request.get('key') #get url safe key from the request
product_key= ndb.Key(urlsafe=urlsafe_key) #Turn it into a real key object
product= product_key.get() #get the object from the database
Creating a Model
1) Creating a model for product in the python:
class Product(ndb.Model):
productname=ndb.StringProperty()
description=ndb.TextProperty()
price=ndb.IntegerProperty()
sold_out= ndb.BooleanProperty()
sell_count= ndb.IntegerProperty() #find popularity of which items are sold the most
2) In my html I will need a form that will have one field for each property that the user (the seller on ebay) needs to supply. In general the property variable name should be the same as the name in your html form.
<form action="/product" method="post">
<input type="text" name="productname">
<textarea name="description"></textarea>
<input name="price" type="number">
<input name="sold_out" type="checkbox" value="1">
<button>Submit</button>
</form>
3) Back in the Python I will have a handler called something like “ProductHandler”
class ProductHandler(webapp2.RequestHandler):
def get(self):
pass
def post(self):
1)Read the request from everything in the form
name= self.request.get('name')
description= self.request.get('description')
price= int(self.request.get('price'))
sold_out= bool(self.request.get('sold_out'))
2)Construct a class for the properties and saves in the database
product= Product(name=name,
description=description
price=price
sold_out=sold_out)
product.put()
3)Send Response
self.redirect('/product?key=' + product.key.urlsafe())
Asking the database to return all the models
- query().fetch()- asking the database and returns a list of models
- get()- returns a single model
- put() - store in data base
How do you ask the database to get all of the things of a certain kind if all the products are in the same product model?
all_product = Product.query().fetch()
all_people = Person.query().fetch()
all_posts = Post.query().fetch()
What if I don’t want all of the things in a certain kind but want to filter? (ex. All the products that are sold out in the product model)
- A filter goes in the query to only return certain models
- A filter always has the form ‘Model.property==value’
available_product= Product.query(Product.sold_out == False).fetch()
affordable_products= Product.query().fetch(Product.price < 100).fetch()
post_for_a_user=Post.query(Post.user == current_user).fetch()
Key Properties
- Think of key properties as an arrow from one model to another
- Keys are like phone numbers where you can call the object and ask for all of its properties
- Keys let you get or fetch a full object with properties associated with it
- You can also use objects to access the key property
- Every model has a key, you don’t need to define a key. You access it with model.key
URL Safe Key: used to pass sensitive information
-
If you’re linking to a page that represents a model in the html template:
<a href="/detail?key=">See details about this model</a>
-
If you are passing a url safe key in a form that you don’t want to show the user:
<form action="/something" method="post">
<input type="hidden" name="model_key" value="">
</form>
- This is necessary if I am having user edit something related to the model or if I am adding information about the model (like a comment on a blogpost)
One to Many Relationships
How do we relate models to one another? One user to many posts. In a one-to-many relationship, each of the “many” has the key property pointing to the “one.”
This allows us to: a. Get the “one” that owns the “many” b. Get all of the “many” that belong to the one
class Mom(ndb.Model)
name = ndb.StringProperty()
class Child(ndb.Model)
name= ndb.StringProperty()
mom_key= ndb.KeyProperty(kind=Mom)
preschool_key = ndb.KeyProperty(kind=Preschool)
a. Get the “one” that owns the “many” We are on a page /child?key=… We want to show the information about the mom of the child:
class ChildHandler(webapp2.RequestHandler):
def get(self):
child_key_urlsafe= self.request.get('key') #get the url safe key from the url
child_key= ndb.Key(urlsafe=child_key_urlsafe) #construct a key from the urlsafe key
child= child_key.get() # we are getting the full child object
mom_key= child.mom_key #
mom = mom_key.get() #
b. What if we are on the /mom?key=… And we want to show the information about the mom of the child:
class MomHandler(webapp2.RequestHandler):
def get(self):
mom_key_urlsafe=self.request.get('key') #get the url safe key from the url
mom_key= ndb.Key(urlsafe=mom_key_urlsafe) #construct a key from the urlsafe key
mom = mom_key.get() #we are getting the full mom object
children = Child.query(Child.mom_key=mom_key).fetch() #get all the children for the mom using a query by filtering the mom.key that identifies the mom. We want to compare keys with keys
Further Examples:
Creating a new model example:
class Bid(ndb.Model):
product_key =ndb.KeyProperty(kind=Product)
class ProductHandler(webapp2.RequestHandler)
def get(self):
#1 Read the request
item_id=self.request.get('item')
#2 Logic/interact with the DB three ways to create a keys. Why do we need to make keys? Keys can only communicate with keys
item_key=ndb.Key(Product, item_id)
bids= Bid.query(product_key== item_key).fetch() #we need to filter these bids by matching the bids product key with the item key
#3 Send a response.
template= env.get_template('bid-page.html')
template_values={"bids":bids, "items": item}
self.response.write(template.render(template_values))
One to One Relationship Example:
Add one player to a team:
from google.appengine.ext import ndb
class Team(ndb.Model):
name = ndb.StringProperty()
class Player(ndb.Model):
name = ndb.StringProperty()
team = ndb.KeyProperty(kind=Team)
warriors_key = ndb.Key(Team,'warriors')
warriors= Team(name="Warriors", id="warriors")
warriors.put()
#Adds new player named curry
curry = Player(name="Stephen Curry", team= warriors.key, id="curry")
curry.put()
One to Many relationship:
Add a new player to the same team:
thompson = Player(name="Klay Thompson", team= warriors_key, id="thompson")
thompson.put()
Many to Many relationships:
A website with multiple products and buyers:
from google.appengine.ext import ndb
class Product(ndb.Model):
name= ndb.StringProperty()
class Buyer(ndb.Model):
name= ndb. StringProperty()
class ProductBuyer(ndb.Model):
product= ndb.KeyProperty (kind=Product)
buyer= ndb.KeyProperty (kind=Buyer)
projector= Product(name= "Book", id="book")
projector.put()
screen= Product(name= "Clothes", id="clothes")
screen.put()
georgia= Buyer(name="Georgia", id="georgia")
georgia.put()
carter= Buyer(name="Carter", id="carter")
carter.put()
ProductBuyer(product=books.key, buyer=carter.key).put()
ProductBuyer(product=clothes.key,buyer=georgia.key).put()
ProductBuyer(product=books,key,buyer=georgia.key).put()
# Search for all the product buyers
screen_key=nbd.Key(Product, "screen")
screen_buyer=PRoductBuyer.query(ProductBuyer.product == screen_key).fetch()