Disable Entity Tracking



Disable tracking for a specific entity in a session

  • Tracking can be disabled for a specific entity in the session.
  • Once tracking is disabled for the entity then:
    • Any changes made to this entity will be ignored for save_changes.
    • Performing another load for this entity will Not generate another call to the server.

Example

# Load a product entity, the session will track its changes
product = session.load("products/1-A", Product)

# Disable tracking for the loaded product entity
session.ignore_changes_for(product)

# The following change will be ignored for save_changes
product.units_in_stock += 1
session.save_changes()

Syntax

def ignore_changes_for(self, entity: object) -> None: ...
Parameters Type Description
entity object Instance of entity for which changes will be ignored

Disable tracking for all entities in a session

  • Tracking can be disabled for all entities in the session's options.
  • When tracking is disabled for the session:
    • Method store will Not be available (an exception will be thrown if used).
    • Calling load or query will generate a call to the server and create new entities instances.

with store.open_session(
    SessionOptions(
        # Disable tracking for all entities in the session's options
        no_tracking=True
    )
):
    # Load any entity, it will Not be tracked by the session
    employee1 = session.load("employees/1-A", Employee)

    # Loading again from same document will result in a new entity instance
    employee2 = session.load("employees/1-A", Employee)

    # Entities instances are not the same
    self.assertNotEqual(employee1, employee2)

Disable tracking for query results

  • Tracking can be disabled for all entities resulting from a query.

with store.open_session() as session:
    # Define a query
    employees_results = list(
        session.advanced.document_query(object_type=Employee)
        # Set no_tracking, all resulting entities will not ne tracked
        .no_tracking().where_equals("FirstName", "Robert")
    )

    # The following modification will not be tracked for save_changes
    first_employee = employees_results[0]
    first_employee.last_name = "NewName"

    # Change to 'first_employee' will not be persisted
    session.save_changes()

Customize tracking in conventions

  • You can further customize and fine-tune which entities will not be tracked
    by configuring the should_ignore_entity_changes convention method on the document store.
  • This customization rule will apply to all sessions opened for this document store.
  • Implement rules under your ShouldIgnoreEntityChanges subclass.
    Apply the class's check method to control the ignore flow.

Example:

with DocumentStore() as store:
    # Define the 'ignore' convention on your document store:

    # Create a class that implements 'ravendb.documents.conventions.ShouldIgnoreEntityChanges'
    # and implement 'check' method - it's going to be called to check if entity should be ignored

    class MyCustomShouldIgnoreEntityChanges(ShouldIgnoreEntityChanges):
        def check(self, session_operations: DocumentSession, entity: object, document_id: str) -> bool:
            # Define for which entities tracking should be disabled
            # Tracking will be disabled ONLY for entities of type Employee whose FirstName is Bob
            return isinstance(entity, Employee) and entity.first_name == "Bob"

    store.conventions.should_ignore_entity_changes = MyCustomShouldIgnoreEntityChanges

    store.initialize()

    with store.open_session() as session:
        employee1 = Employee(first_name="Alice", Id="employees/1")
        employee2 = Employee(first_name="Bob", Id="employees/2")

        session.store(employee1)  # This entity will be tracked
        session.store(employee2)  # Changes to this entity will be ignored

        session.save_changes()

        employee1.first_name = "Bob"  # Changes to this entity will now be ignored
        employee2.first_name = "Alice"  # This entity will now be tracked

        session.save_changes()

Syntax:

@should_ignore_entity_changes.setter
def should_ignore_entity_changes(self, value: ShouldIgnoreEntityChanges) -> None: ...

class ShouldIgnoreEntityChanges(ABC):
    @abstractmethod
    def check(
        self,
        session_operations: "InMemoryDocumentSessionOperations",
        entity: object,
        document_id: str,
    ) -> bool:
        pass
Parameter Type Description
entity object The entity for which tracking is to be disabled
document_id str The entity's document ID
Return Type Description
bool True - Entity will Not be tracked
False - Entity will be tracked