importre
__all__ = ["Style", "MixedCaseUnderscoreStyle", "DefaultStyle",
"MixedCaseStyle"]
[docs]
classStyle(object):
"""
The base Style class, and also the simplest implementation. No
translation occurs -- column names and attribute names match,
as do class names and table names (when using auto class or
schema generation).
"""
def__init__(self, pythonAttrToDBColumn=None,
dbColumnToPythonAttr=None,
pythonClassToDBTable=None,
dbTableToPythonClass=None,
idForTable=None,
longID=False):
if pythonAttrToDBColumn:
self.pythonAttrToDBColumn = \
lambda a, s=self: pythonAttrToDBColumn(s, a)
if dbColumnToPythonAttr:
self.dbColumnToPythonAttr = \
lambda a, s=self: dbColumnToPythonAttr(s, a)
if pythonClassToDBTable:
self.pythonClassToDBTable = \
lambda a, s=self: pythonClassToDBTable(s, a)
if dbTableToPythonClass:
self.dbTableToPythonClass = \
lambda a, s=self: dbTableToPythonClass(s, a)
if idForTable:
self.idForTable = lambda a, s=self: idForTable(s, a)
self.longID = longID
[docs]
defpythonAttrToDBColumn(self, attr):
return attr
[docs]
defdbColumnToPythonAttr(self, col):
return col
[docs]
defpythonClassToDBTable(self, className):
return className
[docs]
defdbTableToPythonClass(self, table):
return table
[docs]
defidForTable(self, table):
if self.longID:
return self.tableReference(table)
else:
return 'id'
[docs]
defpythonClassToAttr(self, className):
return lowerword(className)
[docs]
definstanceAttrToIDAttr(self, attr):
return attr + "ID"
[docs]
definstanceIDAttrToAttr(self, attr):
return attr[:-2]
[docs]
deftableReference(self, table):
return table + "_id"
[docs]
classMixedCaseUnderscoreStyle(Style):
"""
This is the default style. Python attributes use mixedCase,
while database columns use underscore_separated.
"""
[docs]
defpythonAttrToDBColumn(self, attr):
return mixedToUnder(attr)
[docs]
defdbColumnToPythonAttr(self, col):
return underToMixed(col)
[docs]
defpythonClassToDBTable(self, className):
return className[0].lower() \
+ mixedToUnder(className[1:])
[docs]
defdbTableToPythonClass(self, table):
return table[0].upper() \
+ underToMixed(table[1:])
[docs]
defpythonClassToDBTableReference(self, className):
return self.tableReference(self.pythonClassToDBTable(className))
[docs]
deftableReference(self, table):
return table + "_id"
DefaultStyle = MixedCaseUnderscoreStyle
[docs]
classMixedCaseStyle(Style):
"""
This style leaves columns as mixed-case, and uses long
ID names (like ProductID instead of simply id).
"""
[docs]
defpythonAttrToDBColumn(self, attr):
return capword(attr)
[docs]
defdbColumnToPythonAttr(self, col):
return lowerword(col)
[docs]
defdbTableToPythonClass(self, table):
return capword(table)
[docs]
deftableReference(self, table):
return table + "ID"
defaultStyle = DefaultStyle()
defgetStyle(soClass, dbConnection=None):
if dbConnection is None:
if hasattr(soClass, '_connection'):
dbConnection = soClass._connection
if hasattr(soClass.sqlmeta, 'style') and soClass.sqlmeta.style:
return soClass.sqlmeta.style
elif dbConnection and dbConnection.style:
return dbConnection.style
else:
return defaultStyle
############################################################
# Text utilities
############################################################
_mixedToUnderRE = re.compile(r'[A-Z]+')
defmixedToUnder(s):
if s.endswith('ID'):
return mixedToUnder(s[:-2] + "_id")
trans = _mixedToUnderRE.sub(mixedToUnderSub, s)
if trans.startswith('_'):
trans = trans[1:]
return trans
defmixedToUnderSub(match):
m = match.group(0).lower()
if len(m) > 1:
return '_%s_%s' % (m[:-1], m[-1])
else:
return '_%s' % m
defcapword(s):
return s[0].upper() + s[1:]
deflowerword(s):
return s[0].lower() + s[1:]
_underToMixedRE = re.compile('_.')
defunderToMixed(name):
if name.endswith('_id'):
return underToMixed(name[:-3] + "ID")
return _underToMixedRE.sub(lambda m: m.group(0)[1].upper(),
name)