[sqlalchemy] Re: Automatically execute a procedure on saving/loading from Sql database with SQLAlchemy (and MeGrok)

2010-10-25 Thread Hector Blanco
Wow... I just saw this...
http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/types.html#sqlalchemy.types.TypeDecorator
Maybe that's what I need! I'll confirm (for future questions) :-)

2010/10/25 Hector Blanco white.li...@gmail.com

 Hello everyone.

 First of all, thank you for reading this (no matter whether you can/want to
 help me or not) :-)

 Second, the question:

 I am using sqlalchemy under MeGrok (http://pypi.python.org/pypi/megrok.rdb)
 to have my Python/Grok classes stored over a RDBMS (MySql) database.

 I have a Python class in which one of the fields is a list of strings. I
 don't really find worthy to create a table to relate the class with the
 fields (is just a list that can take certain names of days of the week) so I
 was planning to store them in MySql as an string where the values would be
 separated with a comma (or semicolon).

 On the other hand, is very useful to have that field as a list (in Python
 classes) so here's my question:

 Is there a way to automatically execute an stored procedure (SQL
 preferably, but I could also 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)?

 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()*... :-)

 I also asked this very same question in the Grok-dev mail list. They
 suggested me the use of decorators, which I find an interesting idea, but I
 don't really know where to put a decorator to ensure that when that field is
 saved, it's saved as an array, and when it's loaded, it's loaded as a list.

 Oh, and, for the record, I am a newbie with this Grok over MySql thing so
 it may not make any sense what I just asked but... I had to try.

 Thank you in advance.



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Automatically execute a procedure on saving/loading from Sql database with SQLAlchemy (and MeGrok)

2010-10-25 Thread Hector Blanco
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 SimpleDict(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! :)

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Automatically execute a procedure on saving/loading from Sql database with SQLAlchemy (and MeGrok)

2010-10-25 Thread Hector Blanco
I hate when the identation gets messed up... Gonna try again:

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