[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 13:20:14 EDT 2010
[ I hate when the identation gets messed up... Gonna try again ]
Yuuup... Type decorators was a right solution:
http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/types.html#sqlalchemy.types.TypeDecorator
Yuuup... It works like a charm!
I have created a simple class that gets a dictionary and "serializes"
its values. The underlying database is MySql...
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 ZepSimpleDict(types.TypeDecorator):
impl = types.String
size = -1
__separatorChar = chr(0x1D)
__boolPrefix = "b_"
__intPrefix = "i_"
__floatPrefix = "f_"
__nullPrefix = "n_"
__specialPrefixes = set([__boolPrefix, __intPrefix, __floatPrefix,
__nullPrefix])
__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)
else:
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
else:
retval = value
elif prefix == self.__floatPrefix:
try:
retval = float(actualValue)
except ValueError:
retval = value
elif prefix == self.__intPrefix:
try:
retval = int(actualValue)
except ValueError:
retval = value
elif prefix == self.__nullPrefix:
if actualValue == str(None):
retval = None
else:
retval = value
else:
retval = value
else:
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)
else:
value_tmp = None
if (value_tmp is not None):
for key, val in value_tmp.iteritems():
flattenedValue.append(key)
flattenedValue.append(val)
retval = self.__separatorChar.join(flattenedValue)
else:
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! :)
More information about the Grok-dev
mailing list