Saving

There are a couple of different approaches that can be taken when writing data to a MongoDB database. Simon provides a few different methods to perform writes to help expose the full power of each.

Document Replacement

The basic way to create or update a document is with the save() method. It will save the document associated with the instance to the database. If an update is being performed, the version of the document in the database will be overwritten by the version associated with the instance. This is known as document replacement. Any changes made to the version of the document in the database that have not been introduced to the instance will be lost.

user = User(name='Simon')
user.save()

This can be condensed into one step using the create() method.

user = User.create(name='Simon')

save() can also be used to save changes to a document.

user.email = 'simon@example.com'
user.save()

The first of these calls to save() will result in an insert. The second will result in an update. In the mongo Shell they would be written as:

db.users.insert({name: 'Simon'})

db.users.update({_id: ObjectId(...)}, {email: 'simon@example.com'})

Atomic Updates

MongoDB also offers a more powerful way to save changes to documents: atomic updates. By utilizing atomic updates, you can write selective changes to portions of a document without replacing the whole thing. Simon provides several different ways to perform atomic updates.

save_fields

The save_fields() method will perform an atomic update updating only the specified fields.

# update only the score field
user.score = 100
user.save_fields('score')

You can also update multiple fields at once.

user.score = 200
user.friends = ['Alvin', 'Theodore']
user.save_fields(['score', 'friends'])

In the mongo Shell these would be:

db.users.update({_id: ObjectId(...)}, {$set: {score: 100}})

db.users.update({_id: ObjectId(...)}, {$set: {score: 200, friends: ['Alvin', 'Theodore']}})
update

The update() method provides a shortcut to the behavior offered by save_fields().

user.update(score=100)

user.update(score=200, friends=['Alvin', 'Theodore'])
increment

The increment() method provides a way to increment the values of the specified fields. If the field does not exist, it will be added with the initial value of 0.

When incrementing only one field, only the name of the field needs to be given to increment(). A value can also be provided if incrementing by any value other than 1.

user.increment('score')

user.increment('score', 100)

increment() can also be used to increment multiple fields at once.

user.increment(score=100, level=1)

The equivalent queries in the mongo Shell would be:

db.users.update({_id: ObjectId(...)}, {$inc: {score: 1}})

db.users.update({_id: ObjectId(...)}, {$inc: {score: 100}})

db.users.update({_id: ObjectId(...)}, {$inc: {score: 100, level: 1}})
remove_fields

The remove_fields() method will remove the specified fields from the document in the database.

Using it works just like save_fields().

user.remove_fields('level')

user.remove_fields(['level', 'friends'])

To execute these same queries in the mongo Shell:

db.users.update({_id: ObjectId(...)}, {$unset: {level: 1}})

db.users.update({_id: ObjectId(...)}, {$unset: {level: 1, friends: 1}})
raw_update

The raw_update() method allows any update query to be specified.

This method will let you execute any update that can’t appropriately be expressed through one of the other methods. Just make sure you use it with caution as Simon can do little to protect you.

user.raw_update({'$set': {'level': 1}, '$inc': {'score': 100}, '$unset': {'friends': 1}})

This query would be passed through to MongoDB as:

db.users.update({_id: ObjectId(...)}, {$set: {level: 1}, $inc: {score: 100}, $unset: {friends: 1}})

Write Concern

When Simon was first started, the default behavior with MongoDB was to perform writes without write concern. This led to faster performance but had the potential for data loss. Queries performed with write concern enabled will request the result of getLastError() before returning execution to the application. More information is available in the MongoDB Docs.

Simon was built with respect for this behavior as the default. All of the methods discussed above as well as delete() accept an argument called safe that can override the default behavior.

user = User(name='Simon')
user.save(safe=True)

user.update(email='simon@example.com', safe=True)

user.delete(safe=True)

This also applies to the get_or_create() method discussed in Querying.

Table Of Contents

Previous topic

Querying

Next topic

Connecting to a Database

This Page

Fork me on GitHub