[Grok-dev] Automatically execute a procedure on saving/loading from Sql database with MeGrok and SQLAlchemy

Hector Blanco white.lists at gmail.com
Mon Oct 25 12:47:35 EDT 2010

Yuuup...  Type decorators was a right solution:


It works like a charm!

I have created a simple class that gets a dictionary and "serializes" its
values. As I explained in other messages, the underlying database is

Just in case my code may help someone (or if someone has any suggestions...)
here it goes:

from sqlalchemy import types
import logging
log = logging.getLogger(__name__)

class SimpleDict(types.TypeDecorator):
 impl = types.String
 size = -1
 __separatorChar = chr(0x1D)
 __boolPrefix = "b_"
 __intPrefix = "i_"
 __floatPrefix = "f_"
 __nullPrefix = "n_"
 __specialPrefixes = set([__boolPrefix, __intPrefix, __floatPrefix,
 __nullValues = set(["null", "None"])

def __init__(self, length = 1024):
 self.size = int(length)
 super(ZepSimpleDict, self).__init__(self.size)

def __toString(self, value):
 retval = None
 if isinstance(value, bool):
 retval = self.__boolPrefix + str(value)
 elif isinstance(value, float):
 retval = self.__floatPrefix + str(value)
 elif isinstance(value, int):
 retval = self.__intPrefix + str(value)
 elif (value is None) or (value in self.__nullValues):
 retval = self.__nullPrefix + str(None)
 retval = str(value)
 return retval

def __fromString(self, value):
 retval = None
 prefix = None
 actualValue = None
 if len(value) > 2:
 prefix = value[0:2]
 if (prefix in self.__specialPrefixes):
 actualValue = value[2:]
 if prefix == self.__boolPrefix:
 if actualValue == "True":
 retval = True
 elif actualValue == "False":
 retval = False
 retval = value
 elif prefix == self.__floatPrefix:
 retval = float(actualValue)
 except ValueError:
 retval = value
 elif prefix == self.__intPrefix:
 retval = int(actualValue)
 except ValueError:
 retval = value
 elif prefix == self.__nullPrefix:
 if actualValue == str(None):
 retval = None
 retval = value
 retval = value
 retval = value
 return retval

 def process_bind_param(self, value, dialect):
 value_tmp = None
 flattenedValue = list()
 retval = None

if isinstance(value, dict):
 value_tmp = dict()
 for key, val in value.iteritems():
 value_tmp[self.__toString(key)] = self.__toString(val)
 value_tmp = None

if (value_tmp is not None):
 for key, val in value_tmp.iteritems():
 retval = self.__separatorChar.join(flattenedValue)
 retval = None
 return retval

def process_result_value(self, value, dialect):
 retval = dict()
 value_tmp = value.split(self.__separatorChar)
 if (len(value_tmp) > 0):
 if (len(value_tmp) % 2 != 0):
 log.warn("process_result_value > Processing an string with odd number of
elements. This should not have happened.")
 for i in range(0, len(value_tmp), 2):
 retval[self.__fromString(value_tmp[i])] = self.__fromString(value_tmp[i+1])
 return retval

In my previous message, I said:
*In my brain, I have "dreamed" about something like an special type
of sqlalchemy.Column in which you can specify something like "on_save =
execute this()" and "on_load = execute that()"... *

This does exactly that! :) Thank you, Jan for the hint!

2010/10/25 Jan-Wijbrand Kolman <janwijbrand at gmail.com>

> On 10/23/10 00:36 , Hector Blanco wrote:
> > Is there a way to automatically execute an stored procedure (SQL
> > preferably, but I could do it on the "Python" side) so when the class is
> > saved, that list field will be automatically joined (with whatever
> > separator character) and when the class (or that field) is loaded, it
> > will be automatically split-ed (so it will come back as a list)?
> I'm not using Grok in combination with a RDBM, but, would a decorator be
> usefull in this case? The decorated function could be the facade for the
> actual stored value and do the joining in the setter and the spltting in
> the getter.
> HTH,
> regards, jw
> _______________________________________________
> Grok-dev mailing list
> Grok-dev at zope.org
> https://mail.zope.org/mailman/listinfo/grok-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.zope.org/pipermail/grok-dev/attachments/20101025/a0cb15e1/attachment-0001.html 

More information about the Grok-dev mailing list