PyOrient OGM - Batch Operations
The Object-Graph Mapper provides basic support for transactions. This allows you to group several operations together and execute them in a batch on the OrientDB database. You may find this useful in ensuring concurrency as well as reducing the round-trip time on the given operation.
Using Batch Transactions
Transactions in PyOrient use a similar workflow to transactions in OrientDB. That is, you start by beginning the transaction, perform various operations as part of it, then commit those changes to the database.
Initializing Batch Transactions
Unlike standard operations with the OGM, batch transactions operate on a separate object from the OGM
Graph class. Instead, you use the
batch() method to initialize a control object for the transaction. You can then direct operations on OrientDB through this object, only committing it to OrientDB when you're ready.
# Initialize Batch Transaction batch = graph.batch()
Once you've initialized the control object through the
batch() method, you can begin building the transaction. For instance, consider the example of a smart home application that uses OrientDB for back-end storage. While home built systems often have the database server on premises, let's say that you expect some homes to rely on a remote database accessed through the internet.
In situations like this, database initialization can prove difficult, since it would involve multiple network requests to OrientDB. Instead you can group this process into a batch transaction handled through a single network operation.
In preparing a batch operation to initialize the database, you might start by initializing the classes that you want to create:
# Initialize Sensor Class class Sensor(Node): element_type = 'sensor' element_plural = 'sensors' name = String(multibyte = False, unique = True) node_type = String(multibyte = False) # Initialize Zone Class class Zone(Node): element_type = 'zone' element_plural = 'zones' name = String(multibyte = False, unique = True) zone_type = String(multibyte = False) # Initialize Position Class class SensorPosition(Relationship): label = 'position'
Here, you create three classes: two vertex classes for sensors and zones in the house, and an edge class for to position the sensors in particular zones. The special attribute
element_type is redundant here, but it allows you to tell the mapper what name to use for the corresponding schema class.
With the classes created, you can create particular instances of these classes, then adding them to the batch transaction:
# Create Pollen Sensor batch['pollen-sensor-1452'] = batch.sensors.create( name = 'ARDUINO-UNO-1432', node_type = 'pollen') # Create Light Sensor batch['light-sensor-259'] = batch.sensors.create( name = 'ARDUINO-UNO-259', node_type = 'light-sensor') # Create Bedroom Zone batch['master-bedroom'] = batch.zones.create( name = 'master', zone_type = 'bedroom'
This creates three vertices in the batch: one for an Arduino device built as a pollen sensor, one for a light sensor, and one for a zone for the master bedroom.
With the vertices created, you can also create edges to connect them. In doing so, you have the option of two syntax methods for the operation.
# Place Pollen Sensor (Method 1) batch[:] = batch.position.create( batch[:'pollen-sensor-1452'], batch[:'master-bedroom']).retry(20) # Place Light Sensor (Method 2) batch[:] = batch[:'light-sensor-259'](SensorPosition) > batch[:'master-bedroom']
In the example, notice that in both cases the code defines the relationship using slice syntax. You can do this in cases where you don't need to reference the edge later in the batch transaction.
In the event that you would like to perform further operations on the code before committing the transaction, batches provide an optional return value. You can retrieve this value from the control object:
# Fetch Pollen Sensor Return Value pollen = batch['$pollen-sensor-1452']
This retrieves the return value and sets it on the
Committing Batch Transactions
When you're finished with the batch transaction, you can commit it to OrientDB using the
# Cmmmit Batch Transaction batch.commit()
When you issue this method, PyOrient sends a network request to OrientDB, then executes each operation in the batch through that single request, without the need for the usual back and forth between the two.