It’s no secret that Storm documentation is terrible. Canonical has no interest in making it better as it is like this for a big while already. Storm is used on its product and that’s it. It’s good enough for them. So, whenever I need to solve a specific problem, I am diving deeply into Storm’s code.
Storm supports allow_none when defining a model, where you can set a NOT NULL behavior. Strangely, though, the way that Storm deals with this is rather… Odd.
If we have a model, which the ‘value’ field is allow_none=False (NOT NULL, indeed), Storm only raises a NoneError exception if we try to set explicitly model.value = None.
In another words, if you set all other fields and try to save it, it will not fail, but will rather insert a ‘default’ value (even if you don’t have a default value defined!). It inserts 0 for integers, 0.0 for decimals and an empty string for varchar. Why doesn’t Storm raises an NoneError when creating the model but instead it inserts a ‘default’ value ? Looking into Storm’s code, seems like this verification is only done when setting the variable, never at commit-level. So I needed to figure out a way of doing this verification before ever committing a store.
For this, before Storm commits any store, it flushes its data, and before doing that, it calls a __storm_pre_flush__ method that should be implemented on your model. This method is always called before committing, so we can use it to implement interesting stuff.
In my case, I implemented a loop inside this method, that traverses all columns of the model. On the first one that can find that doesn’t have a value set, and doesn’t have a default specified and do not allow None (allow_none=False), I set it to none, letting storm do its job and raising NoneError from the variable set.
PS: Mamba framework has a better documentation on Storm than Storm itself. With some rather nice features added on top.