A state machine is an abstract machine that can be in one of a finite number of states. The machine is in only one state at a time; the state it is in at any given time is called the current state.
While using the database, individual records should be in allowed states. The database or application stores rules for the states. There are many ways to design the database schema to achieve this. The most followed methods are using
string field, where each value represents a state. Above is the direct method approach. An indirect and unaware method is the use of multiple boolean values to calculate the state. Like
is_published. The combination of two fields shows four different states.
At work, the similar situation arose. First, it started with single boolean value and after some time, the second column showed up. Then, of course, the third one. That’s when I realized; use
state machine. I spent time looking up a relevant library and meet transition. The library supports
state change validation.
Consider a simple model
Order with five states.
'placed', 'dispatched', 'delivered', 'canceled', 'returned'. Well, real world model will have way more states. The important point of these states, object transition should follow rules. An order can be in
returned state when the previous state was
delivered. And this requires custom validation code with multiple
if conditions. Here is state machine diagram.
When the number of states increases, the code starts to fall apart with
Transition library supports the declaration of
allowed triggers and takes care of validation. It provides a set of helper methods to do transitions. Here is a simple example.
Machine class takes a list of
Transitions is a collection of iterable with
start state and
destination state as arguments respectively.
To trigger an event, invoke
machine.model.<trigger>(). Method returns
True when the trigger succeeds and
False when the trigger isn’t allowed in the current state. The machine calculates the logic from the list of configured transitions.
Delivery isn’t possible with the canceled order!
ignore_invalid_triggers=True makes the method to return
False. The library raise
MachineError Exception when
ignore_invalid_triggers is set to
Declarative style of creating state machine makes the library easy to use and prevents a lot of boilerplate code.
- Five reasons to use Py.test
- Build Plugins with Pluggy
- Render local images in datasette using datasette-render-local-images
- Parameterize Python Tests
- “Don’t touch your face” - Neural Network will warn you
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.