Sling Academy
Home/Python/MongoEngine Upsert: Insert if not exists, update if exists

MongoEngine Upsert: Insert if not exists, update if exists

Last updated: February 10, 2024

Introduction

When working with databases, a common requirement is to update a record if it exists or insert it as a new one if it doesn’t. This operation is commonly known as upsert, which stands for UPdate + inSERT. In the context of MongoDB, this can be achieved using the MongoEngine ODM (Object Document Mapper) in Python. This tutorial will guide you through implementing upserts with MongoEngine, progressing from basic to advanced usage, complete with code examples and expected outputs.

Getting Started with MongoEngine

Before diving into upserts, ensure you have MongoEngine installed and configured in your Python environment. Install MongoEngine using pip:

pip install mongoengine

Connect to your MongoDB instance:

from mongoengine import connect
connect('your_database_name', host='localhost', port=27017)

Basic Upsert Operation

Upserting with MongoEngine can be done using the update_one function with upsert=True. Here’s a simple example:

from mongoengine import Document, StringField, connect

class User(Document):
    name = StringField(required=True)
    email = StringField(required=True)

connect('user_db', host='localhost', port=27017)

user = {'name': 'John Doe', 'email': '[email protected]'}
User.objects(name=user['name']).update_one(upsert=True, **user)

This code checks if a user with the name ‘John Doe’ exists. If not, it inserts a new document with the provided ‘name’ and ’email’. If a document with such a name already exists, it will update the existing record.

Conditional Upsert

Let’s say you only want to perform an upsert based on certain conditions, such as updating the email of a user only if the current email matches a specific pattern. For this use case, you can utilize MongoEngine’s condition parameters:

user = {'name': 'Jane Doe', 'email': '[email protected]'}
User.objects(name=user['name'], email__icontains='@example.com').update_one(upsert=True, set__email=user['email'])

This updates ‘Jane Doe’s email only if the existing email contains ‘@example.com’. Otherwise, if no record matches the conditions, it inserts a new document.

Complex Upsert Scenarios

For more complex upsert operations involving embedded documents or arrays, you would typically use modify in conjunction with searching and updating or inserting as needed:

from mongoengine import EmbeddedDocument, EmbeddedDocumentField, ListField

class Address(EmbeddedDocument):
    street = StringField()
    city = StringField()

class Person(Document):
    name = StringField(required=True)
    addresses = ListField(EmbeddedDocumentField(Address))

connect('people_db', host='localhost', port=27017)

# Upsert an embedded document
person_name = 'Emily Clark'
new_address = {'street': '123 Elm Street', 'city': 'Gotham'}
Person.objects(name=person_name).modify(upsert=True, new=True, add_to_set__addresses=new_address)

This example uses modify with upsert=True and new=True to ensure that if a person named ‘Emily Clark’ does not exist, a new document is created. If she does exist, her document is updated by adding a new address to her ‘addresses’ list, provided it isn’t already present.

Conclusion

MongoEngine makes working with MongoDB in Python applications straightforward and efficient, particularly when it comes to upsert operations. Whether you’re dealing with simple record updates or complex scenarios involving embedded documents, following the steps outlined in this tutorial will help you implement upserts effectively. The power of upsert lies in its ability to keep your database concise and current without the need for separate insert and update operations.

Next Article: MongoEngine: AND & OR Conditions – Tutorial & Examples

Previous Article: MongoEngine: How to delete documents by a condition

Series: Data Persistence in Python – Tutorials & Examples

Python

You May Also Like

  • Introduction to yfinance: Fetching Historical Stock Data in Python
  • Monitoring Volatility and Daily Averages Using cryptocompare
  • Advanced DOM Interactions: XPath and CSS Selectors in Playwright (Python)
  • Automating Strategy Updates and Version Control in freqtrade
  • Setting Up a freqtrade Dashboard for Real-Time Monitoring
  • Deploying freqtrade on a Cloud Server or Docker Environment
  • Optimizing Strategy Parameters with freqtrade’s Hyperopt
  • Risk Management: Setting Stop Loss, Trailing Stops, and ROI in freqtrade
  • Integrating freqtrade with TA-Lib and pandas-ta Indicators
  • Handling Multiple Pairs and Portfolios with freqtrade
  • Using freqtrade’s Backtesting and Hyperopt Modules
  • Developing Custom Trading Strategies for freqtrade
  • Debugging Common freqtrade Errors: Exchange Connectivity and More
  • Configuring freqtrade Bot Settings and Strategy Parameters
  • Installing freqtrade for Automated Crypto Trading in Python
  • Scaling cryptofeed for High-Frequency Trading Environments
  • Building a Real-Time Market Dashboard Using cryptofeed in Python
  • Customizing cryptofeed Callbacks for Advanced Market Insights
  • Integrating cryptofeed into Automated Trading Bots