[Tkinter-discuss] Tkinter (python 3) and Sql-Alchemy

Russell Adams RLAdams at AdamsInfoServ.Com
Tue Jan 29 15:26:11 CET 2013


> I'm thinking I may need to add a trace that does the sync, not
> override set().

To answer my own question and put it on the ML for future reference,
creating classes for SQL-Alchemy SQL data types that bind a trace
callback does indeed synchronize changes that happen to the widget
onscreen with the SQL-A object.

This is very convenient because my forms are all a single transaction
in the DB, and when the changes are synced my save call is merely
commit.

Thanks.

# ----------------------------------------------------------------------
class stringFieldVar(Variable):
    """Override Tk Variable class to allow sync and validation with SQLA objects"""

    def __init__(self, datum, field):

        self.datum        = datum
        self.field        = field

        super().__init__( value = self._tkConvert(getattr(self.datum, self.field, '')) )
        self.trace("w", self.synchronizeWithSQL)


    def _tkConvert(self, value):
        """Convert to a string for Tk, only used on initial set from DB"""
        if value == None:
            result = ''
        else:
            result = str(value)
        return result


    def _sqlConvert(self, value):
        """Convert a Tk string back to SQL datatype, happens every widget refresh"""
        if value == '':
            result = None
        elif value:
            result = str(value)
        return result


    def synchronizeWithSQL(self, *args):
        """Convert data for DB type, the widget calls this repeatedly with changes"""

        try:
            # only update the sql object if the value is valid
            logger.debug("Testing {}, is '{}' valid?".format(self.field, self.get()))
            sqlValue = self._sqlConvert(self.get())
            setattr(self.datum, self.field, sqlValue)
            logger.debug("Setting {}, converted '{}', to '{}'".format(self.field, self.get(), sqlValue))
        except (AttributeError, TypeError):
            pass



class intFieldVar(stringFieldVar):

    def _sqlConvert(self, value):
        if value == '':
            result = None
        elif value:
            result = int(value)
        return result



class numericFieldVar(stringFieldVar):

    def _sqlConvert(self, value):
        if value == '':
            result = None
        elif value:
            result = D.decimal(value)
        return result



class booleanFieldVar(stringFieldVar):

    def _tkConvert(self, value):
        """Convert to a string for Tk, only used on initial set from DB"""
        if value == None:
            result = ''
        elif value == True:
            result = '1'
        else:
            result = '0'
        return result


    def _sqlConvert(self, value):
        if value == '':
            result = None
        elif value == '1':
            result = True
        else:
            result = False
        return result



class dateFieldVar(stringFieldVar):

    def _tkConvert(self, value):
        return '' if value == None else value.strftime("%Y/%m/%d")


    def _sqlConvert(self, value):
        if value == '':
            result = None
        elif value == 'now':
            result = 'now'
        elif value:
            result = time.strftime("%Y/%m/%d", value)
        return result



class datetimeFieldVar(stringFieldVar):

    def _tkConvert(self, value):
        return '' if value == None else value.strftime("%Y/%m/%d %H:%M:%S")


    def _sqlConvert(self, value):
        if value == '':
            result = None
        elif value == 'now':
            result = 'now'
        elif value:
            result = time.strftime("%Y/%m/%d %H:%M:%S", value)
        return result





------------------------------------------------------------------
Russell Adams                            RLAdams at AdamsInfoServ.com

PGP Key ID:     0x1160DCB3           http://www.adamsinfoserv.com/

Fingerprint:    1723 D8CA 4280 1EC9 557F  66E8 1154 E018 1160 DCB3


More information about the Tkinter-discuss mailing list