Sling Academy
Home/Python/MongoEngine: Set min/max for a number field

MongoEngine: Set min/max for a number field

Last updated: February 10, 2024

Introduction

MongoEngine, an Object-Document Mapper (ODM) for working with MongoDB from Python, offers a convenient way to interact with MongoDB. This tutorial will guide you through setting minimum and maximum values for numerical fields in MongoEngine to ensure your data adheres to expected constraints.

Starting with the Basics

Before diving into min/max constraints, let’s ensure we have a clear understanding of how to define a document in MongoEngine.

from mongoengine import Document, FloatField

class Employee(Document):
    salary = FloatField()

In the example above, we’ve defined an Employee model with a salary field of type FloatField.

Setting Min and Max Values

Here’s how you implement minimum and maximum value constraints:

from mongoengine import Document, FloatField

class Employee(Document):
    salary = FloatField(min_value=30000.0, max_value=200000.0)

This ensures that any salary value outside the range of 30,000 to 200,000 will raise a validation error when you attempt to save an Employee document.

Dynamic Min/Max Values

In some scenarios, you might want the min/max constraints to be dynamic. Here’s how you can achieve this:

from mongoengine import Document, FloatField, signals

class Employee(Document):
    salary = FloatField()

    @classmethod
    def pre_save(cls, sender, document, **kwargs):
        if document.salary < document.min_salary() or document.salary > document.max_salary():
            raise Exception('Salary must be between minimum and maximum values.')

    def min_salary(self):
        return 30000.0

    def max_salary(self):
        return 200000.0

signals.pre_save.connect(Employee.pre_save, sender=Employee)

This method employs signals to check the constraints right before saving the document, allowing for more flexibility in defining min_salary and max_salary.

Custom Validation Logic

Sometimes, min/max checks need additional logic. You might, for example, want different limits based on another field such as job_title:

from mongoengine import Document, FloatField, StringField

class Employee(Document):
    salary = FloatField()
    job_title = StringField()

    def clean(self):
        if self.job_title == 'Manager' and (self.salary < 50000.0 or self.salary > 250000.0):
            raise ValueError('Invalid salary for manager.')
        elif self.job_title != 'Manager' and (self.salary < 30000.0 or self.salary > 200000.0):
            raise ValueError('Invalid salary for this job title.')

The clean method offers a way to incorporate complex validation logic, ensuring the data complies with our business rules.

Utilizing Min/Max Values in Queries

MongoEngine doesn’t restrict using min and max values to field definitions alone; you can also leverage these constraints in your queries:

employees = Employee.objects(salary__gte=30000, salary__lte=200000)

This query fetches Employee documents with salaries within the specified range, demonstrating how MongoEngine supports complex querying operations in a syntactically clear way.

Handling Validation Errors

When a document fails validation due to min/max constraints, MongoEngine raises a ValidationError. Catching and handling these exceptions ensures that your application can provide informative feedback to users:

try:
    employee = Employee(salary=250000.0).save()
except ValidationError as e:
    print(f'Error: {e.message}')

To effectively prevent data integrity issues, it’s critical to understand and apply proper error handling tactics when working with MongoEngine documents.

Conclusion

Setting minimum and maximum values for numeric fields in MongoEngine helps enforce data integrity and business rules. Starting with basic constraints and progressing to dynamic validation and complex logic demonstrates MongoEngine’s flexibility and power in managing MongoDB documents with Python.

Next Article: MongoEngine: Unique and Non-Unique Fields

Previous Article: MongoEngine: Set max length for a text field

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