Commit 0c1c2f20 by O'Reilly Media, Inc

Initial commit

parents
from datetime import datetime
user_doc = {
"username" : "janedoe",
"firstname" : "Jane",
"surname" : "Doe",
"dateofbirth" : datetime(1974, 4, 12),
"email" : "janedoe74@example.com",
"score" : 0
}
""" An example of how to connect to MongoDB """
import sys
from pymongo import Connection
from pymongo.errors import ConnectionFailure
def main():
""" Connect to MongoDB """
try:
c = Connection(host="localhost", port=27017)
print "Connected successfully"
except ConnectionFailure, e:
sys.stderr.write("Could not connect to MongoDB: %s" % e)
sys.exit(1)
if __name__ == "__main__":
main()
""" An example of how to get a Python handle to a MongoDB database """
import sys
from pymongo import Connection
from pymongo.errors import ConnectionFailure
def main():
""" Connect to MongoDB """
try:
c = Connection(host="localhost", port=27017)
except ConnectionFailure, e:
sys.stderr.write("Could not connect to MongoDB: %s" % e)
sys.exit(1)
# Get a Database handle to a database named "mydb"
dbh = c["mydb"]
# Demonstrate the db.connection property to retrieve a reference to the
# Connection object should it go out of scope. In most cases, keeping a
# reference to the Database object for the lifetime of your program should
# be sufficient.
assert dbh.connection == c
print "Successfully set up a database handle"
if __name__ == "__main__":
main()
""" An example of how to insert a document """
import sys
from datetime import datetime
from pymongo import Connection
from pymongo.errors import ConnectionFailure
def main():
try:
c = Connection(host="localhost", port=27017)
except ConnectionFailure, e:
sys.stderr.write("Could not connect to MongoDB: %s" % e)
sys.exit(1)
dbh = c["mydb"]
assert dbh.connection == c
user_doc = {
"username" : "janedoe",
"firstname" : "Jane",
"surname" : "Doe",
"dateofbirth" : datetime(1974, 4, 12),
"email" : "janedoe74@example.com",
"score" : 0
}
dbh.users.insert(user_doc, safe=True)
print "Successfully inserted document: %s" % user_doc
if __name__ == "__main__":
main()
# dbh.usrs is a typo, we mean dbh.users! Unlike an RDBMS, MongoDB won't
# protect you from this class of mistake.
dbh.usrs.insert(user_doc)
# safe=True ensures that your write
# will succeed or an exception will be thrown
dbh.users.insert(user_doc, safe=True)
# w=2 means the write will not succeed until it has
# been written to at least 2 servers in a replica set.
dbh.users.insert(user_doc, w=2)
# Assuming we already have a database handle in scope named dbh
# find a single document with the username "janedoe".
user_doc = dbh.users.find_one({"username" : "janedoe"})
if not user_doc:
print "no document found for username janedoe"
# Assuming we already have a database handle in scope named dbh
# find all documents with the firstname "jane".
# Then iterate through them and print out the email address.
users = dbh.users.find({"firstname":"jane"})
for user in users:
print user.get("email")
# Only retrieve the "email" field from each matching document.
users = dbh.users.find({"firstname":"jane"}, {"email":1})
for user in users:
print user.get("email")
# Find out how many documents are in users collection, efficiently
userscount = dbh.users.find().count()
print "There are %d documents in users collection" % userscount
# Return all user with firstname "jane" sorted
# in descending order by birthdate (ie youngest first)
users = dbh.users.find(
{"firstname":"jane"}).sort(("dateofbirth", pymongo.DESCENDING))
for user in users:
print user.get("email")
# Return all user with firstname "jane" sorted
# in descending order by birthdate (ie youngest first)
users = dbh.users.find({"firstname":"jane"},
sort=[("dateofbirth", pymongo.DESCENDING)])
for user in users:
print user.get("email")
# Return at most 10 users sorted by score in descending order
# This may be used as a "top 10 users highscore table"
users = dbh.users.find().sort(("score", pymongo.DESCENDING)).limit(10)
for user in users:
print user.get("username"), user.get("score", 0)
# Return at most 20 users sorted by name,
# skipping the first 20 results in the set
users = dbh.users.find().sort(
("surname", pymongo.ASCENDING)).limit(20).skip(20)
# Traverse the entire users collection, employing Snapshot Mode
# to eliminate potential duplicate results.
for user in dbh.users.find(snapshot=True):
print user.get("username"), user.get("score", 0)
# run the update query, using the $set update modifier.
# we do not need to know the current contents of the document
# with this approach, and so avoid an initial query and
# potential race condition.
dbh.users.update({"username":"janedoe"},
{"$set":{"email":"janedoe74@example2.com"}}, safe=True)
# update the email address and the score at the same time
# using $set in a single write.
dbh.users.update({"username":"janedoe"},
{"$set":{"email":"janedoe74@example2.com", "score":1}}, safe=True)
# once we supply the "multi=True" parameter, all matched documents
# will be updated
dbh.users.update({"score":0},{"$set":{"flagged":True}}, multi=True, safe=True)
# Delete all documents in user collection with score 1
dbh.users.remove({"score":1}, safe=True)
# Delete all documents in user collection
dbh.users.remove(None, safe=True)
user_doc = dbh.users.find_one({"facebook.username":"foofacebook"})
# update modifiers such as $set also support the dot notation
dbh.users.update({"facebook.username":"foofacebook"},
{"$set":{"facebook.username":"bar"}}, safe=True)
# Atomically remove an email address from a user document race-free using the
# $pull update modifier
user_doc = {
"username":"foouser",
"emails":[
{
"email":"foouser1@example.com",
"primary":True
},
{
"email":"foouser2@example2.com",
"primary":False
},
{
"email":"foouser3@example3.com",
"primary":False
}
]
}
# Insert the user document
dbh.users.insert(user_doc, safe=True)
# Use $pull to atomically remove the "foouser2@example2.com" email sub-document
dbh.users.update({"username":"foouser"},
{"$pull":{"emails":{"email":"foouser2@example2.com"}}}, safe=True)
# Use $push to atomically append a new email sub-document to the user document
new_email = {"email":"fooemail4@exmaple4.com", "primary":False}
dbh.users.update({"username":"foouser"},
{"$push":{"emails":new_email}}, safe=True)
# Demonstrate usage of the positional operator ($) to modify
# matched sub-documents in-place.
user_doc = {
"username":"foouser",
"emails":[
{
"email":"foouser1@example.com",
"primary":True
},
{
"email":"foouser2@example2.com",
"primary":False
},
{
"email":"foouser3@example3.com",
"primary":False
}
]
}
# Insert the user document
dbh.users.insert(user_doc, safe=True)
# Now make the "foouser2@example2.com" email address primrary
dbh.users.update({"emails.email":"foouser2@example2.com"},
{"$set":{"emails.$.primary":True}}, safe=True)
# Now make the "foouser1@example.com" email address not primary
dbh.users.update({"emails.email":"foouser1@example.com"},
{"$set":{"emails.$.primary":False}}, safe=True)
user_doc = {
"username":"foouser",
"emails":[
{
"email":"foouser1@example.com",
"primary":True
},
{
"email":"foouser2@example2.com",
"primary":False
},
{
"email":"foouser3@example3.com",
"primary":False
}
]
}
dbh.users.insert(user_doc)
# If we place an index on property "emails.email",
# e.g. dbh.users.create_index("emails.email")
# this find_one query can use a btree index
user = dbh.users.find_one({"emails.email":"foouser2@example2.com"})
# Create index on username property
dbh.users.create_index("username")
# Create a compound index on first_name and last_name properties
# with ascending index direction
dbh.users.create_index([("first_name", pymongo.ASCENDING), ("last_name", pymongo.ASCENDING)])
# Create a compound index called "name_idx" on first_name and last_name properties
# with ascending index direction
dbh.users.create_index([
("first_name", pymongo.ASCENDING),
("last_name", pymongo.ASCENDING)
],
name="name_idx")
# Create index in the background
# Database remains usable
dbh.users.create_index("username", background=True)
# Create index with unique constraint on username property
dbh.users.create_index("username", unique=True)
# Create index with unique constraint on username property
# instructing MongoDB to drop all duplicates after the first document it finds.
dbh.users.create_index("username", unique=True, drop_dups=True)
# Could equally be written:
# dbh.users.create_index("username", unique=True, dropDups=True)
# Create a compound index on first_name and last_name properties
# with ascending index direction
dbh.users.create_index([("first_name", pymongo.ASCENDING), ("last_name", pymongo.ASCENDING)])
# Delete this index
dbh.users.drop_index([("first_name", pymongo.ASCENDING), ("last_name", pymongo.ASCENDING)])
# Create index on username property called "username_idx"
dbh.users.create_index("username", name="username_idx")
# Delete index called "username_idx"
dbh.users.drop_index("username_idx")
# Create geospatial index on "user_location" property.
dbh.users.create_index([("user_location", pymongo.GEO2D), ("username", pymongo.ASCENDING)])
# Find the 10 users nearest to the point 40, 40 with max distance 5 degrees
nearest_users = dbh.users.find(
{"user_location":
{"$near" : [40, 40],
"$maxDistance":5}}).limit(10)
# Print the users
for user in nearest_users:
# assume user_location property is array x,y
print "User %s is at location %s,%s" %(user["username"], user["user_location"][0],
user["user_location"[1])
box = [[50.73083, -83.99756], [50.741404, -83.988135]]
users_in_boundary = dbh.users.find({"user_location":{"$within": {"$box":box}}})
users_in_circle = dbh.users.find({"user_location":{"$within":{"$center":[40, 40, 5]}}}).limit(10)
# Find the 10 users nearest to the point 40, 40 with max distance 5 degrees
# Uses the spherical model provided by MongoDB 1.8.x and up
earth_radius_km = 6371.0
max_distance_km = 5.0
max_distance_radians = max_distance_km / earth_radius_km
nearest_users = dbh.users.find(
{"user_location":
{"$nearSphere" : [40, 40],
"$maxDistance":max_distance_radians}}).limit(10)
# Print the users
for user in nearest_users:
# assume user_location property is array x,y
print "User %s is at location %s,%s" %(user["username"], user["user_location"][0],
user["user_location"[1])
total_score = 0
for username in ("jill", "sam", "cathy"):
user_doc = dbh.users.find_one({"username":username})
total_score += user_doc.get("score", 0)
# Email each supplier of this product.
# Default value is the empty list so no special casing
# is needed if the suppliers property is not present.
for supplier in product_doc.get("suppliers", []):
email_supplier(supplier)
# Using upsert=True
def edit_or_add_session(description, session_id):
dbh.sessions.update({"session_id":session_id},
{"$set":{"session_description":description}}, safe=True, upsert=True)
# User X adds $20 to his/her account, so we atomically increment
# account_balance and return the resulting document
ret = dbh.users.find_and_modify({"username":username},
{"$inc":{"account_balance":20}}, safe=True, new=True)
new_account_balance = ret["account_balance"]
# Fetch the score for the current week
import datetime
now = datetime.datetime.utcnow()
current_year = now.year
current_week = now.isocalendar()[1]
# Default missing keys to a score of zero
user_doc["scores_weekly"].get("%d-%d" %(current_year, current_week), 0)
# Update the score for the current week
import datetime
username = "foouser"
now = datetime.datetime.utcnow()
current_year = now.year
current_week = now.isocalendar()[1]
# Use atomic update modifier to increment by 24
dbh.users.update({"username":username},
{"$inc":{"scores_weekly.%s-%s" %(current_year, current_week):24}},
safe=True)
# Update the score for the current week
import datetime
username = "foouser"
now = datetime.datetime.utcnow()
current_year = now.year
current_month = new.month
current_week = now.isocalendar()[1]
current_day = now.timetuple().tm_yday
# Use atomic update modifier to increment by 24
dbh.users.update({"username":username},
{"$inc":{
"scores_weekly.%s-%s" %(current_year, current_week):24,
"scores_daily.%s-%s" %(current_year, current_day):24,
"scores_monthly.%s-%s" %(current_year, current_month):24,
"score_total":24,
}
},
safe=True)
from beaker.cache import CacheManager
from beaker.util import parse_cache_config_options
from pymongo import Connection
from pylons import config
class Globals(object):
"""Globals acts as a container for objects available throughout the
life of the application
"""
def __init__(self, config):
"""One instance of Globals is created during application
initialization and is available during requests via the
'app_globals' variable
"""
self.mongodb_conn = Connection(config['mongodb.url'])
self.mongodb = self.mongodb_conn[config['mongodb.db_name']]
self.cache = CacheManager(**parse_cache_config_options(config))
import logging
from pylons import app_globals as g, request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect
from pylonsfoo.lib.base import BaseController, render
log = logging.getLogger(__name__)
class MongodbController(BaseController):
def index(self):
new_doc = g.mongodb.counters.find_and_modify({"counter_name":"test_counter"},
{"$inc":{"counter_value":1}}, new=True, upsert=True , safe=True)
return "MongoDB Counter Value: %s" % new_doc["counter_value"]
import datetime
def my_view(request):
new_page_hit = {"timestamp":datetime.datetime.utcnow(), "url":request.url}
request.db.page_hits.insert(new_page_hit, safe=True)
return {"project":"mongofoo"}
import datetime
import string
import random
import mimetypes
import cStringIO as StringIO
from PIL import Image
from django.http import HttpResponse
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from pymongo.connection import Connection
from pymongo import DESCENDING
import gridfs
db = Connection().sms
## Example files for the title:
# MongoDB and Python, by Niall O'Higgins
[![MongoDB and Python, by Niall O'Higgins](http://akamaicovers.oreilly.com/images/9781449310363/cat.gif)](https://www.safaribooksonline.com/library/view/title/9781449312817//)
The following applies to example files from material published by O’Reilly Media, Inc. Content from other publishers may include different rules of usage. Please refer to any additional usage rights explained in the actual example files or refer to the publisher’s website.
O'Reilly books are here to help you get your job done. In general, you may use the code in O'Reilly books in your programs and documentation. You do not need to contact us for permission unless you're reproducing a significant portion of the code. For example, writing a program that uses several chunks of code from our books does not require permission. Answering a question by citing our books and quoting example code does not require permission. On the other hand, selling or distributing a CD-ROM of examples from O'Reilly books does require permission. Incorporating a significant amount of example code from our books into your product's documentation does require permission.
We appreciate, but do not require, attribution. An attribution usually includes the title, author, publisher, and ISBN.
If you think your use of code examples falls outside fair use or the permission given here, feel free to contact us at <permissions@oreilly.com>.
Please note that the examples are not production code and have not been carefully testing. They are provided "as-is" and come with no warranty of any kind.
This diff is collapsed. Click to expand it.