Title: DBATRIB SUBMITTER: J Knapka (Other Recipes) Last Updated: 2002/01/07 Version No: 1.1 Category: Databases
2 vote (s)
Description: Associate Object Attributes With Database Column. Source: Text SourceImport DBI, ODBC
Class DBCore:
"" "Basic DB Access." "" "
DEF __INIT __ (Self, DBNAME):
Self._db = ODBC.ODBC (DBNAME)
Self._cur = self._db.cursor ()
Def ExecuteUpdate (Self, SQL, * PARMS):
Self._cur.execute (SQL, * PARMS)
Def ExecuteQuery (Self, SQL, * PARMS, ** KWS):
Strip = 0
TRY:
Strip = kWS ['Strip']
Except Keyerror:
PASS
Self._cur.execute (SQL, * PARMS)
Results = self._cur.Fetchall ()
IF Strip:
# Remove Extraneous Sequernne Nesting.
if Len (Results) == 1 and Len (Results [0]) == 1:
Return Results [0] [0]
Return RESULTS
DEF EXECUTE (Self, SQL, * Args, ** kWs):
IF SQL [0: 6] == "SELECT":
Return Self.executeQuery (SQL, * ARGS, ** KWS)
Else:
SELF.EXECUTEUPDATE (SQL, * args, ** kWs)
Class Dbattrib (dbcore):
"" "" "Provides magic for getting and setting attributes
In the Database Via ODBC. "" ""
DEF __INIT __ (Self, DBName, Table, Cols, Where, Wheremparms):
"" "
DBNAME: ODBC Data Source Name.
Table: DB Table Name.
Map of attribute names to names of columns in table.
WHERE: WHERE CLAUSE OF Query To Fetch This Object's Table Data.
WHEREPARMS: SEQUENCE Containing Parameters to
"" "
Self .__ dict __ ['_ db_cols'] = cols
Self._db_table = TABLE
Self._db_where = where
Self._db_whereparms = whereparms
Dbcore .__ init __ (self, dbname)
DEF __SETATTR __ (Self, Attr, Value):
"" "Look for a _Set_attr method. If found, use it. Otherwise, if the
Attribute is a db column, use odbc. Otherwise, set in theobject dict. "" "
TRY:
SetMethod = Getattr (Self, "_ set _" attr)
Return Apply (SetMethod, (Value,))
Except AttributeError:
PASS
IF attr in self._db_cols.keys ():
SELF._DB_SET_ATTR (Attr, Value)
Return
Self .__ dict __ [attr] = Value
DEF __GETATTR __ (Self, Attr):
"" "" "Ignore _SET_ and _db_ attrib s. If there's a _get_attr method,
Use it. OtherWise, IF IT'S A DB Column, Use ODBC. "" "
IF attr [0: 5] == "_SET_":
Raise Attributeerror
IF attr [0: 5] == "_get_":
Raise Attributeerror
IF attr [0: 4] == "_db_":
Raise Attributeerror
TRY:
GetMethod = getattr (Self, "_ get _" attr)
Return Apply (GetMethod)
Except AttributeError:
PASS
IF attr in self._db_cols.keys ():
Return Self._db_get_attr (attr)
Raise Attributeerror
DEF _DB_GET_ATTR (Self, ATTR):
"" "" Get Attr from the Database. "" "
Attr = self._db_cols [attr]
SQL = "SELECT /"% s / "from /"% s / "% s"% (attr, self._db_table,
SELF._DB_WHERE)
Return self.execute (SQL, Self._db_whereparms, strip = 1)
DEF _DB_SET_ATTR (Self, Attr, Value):
"" "" "" "" "" ""
Attr = self._db_cols [attr]
SQL = "Update /"% s / "set /"% s / "=?% s"% (self._db_table,
Attr, Self._db_where)
SELF.EXECUTE (SQL, (Value,) Self._DB_whereparms)
# Example: The "student" Table Has Column "Last Name", "First Name",
# "Middle", and "customer id."
Class Student (DBATTRIB):
DEF __INIT __ (Self, DBNAME, Student_ID):
DBATTRIB .__ init__ (Self,
DBNAME,
'Student',
{'Lastname': 'Last Name', 'Firstname': 'First Name',
'middle': 'middle',
'CustId': 'Customer ID'},
'Where "Customer ID" =?',
(Student_ID,))
Stu = student ("MYDB", "999-9999")
# Fetch db data.
Print stu.custid, stu.lastname, stu.firstname, stu.middle
# Update DB Data.
stu.middle = "X" Discussion: This recipe is a bit lengthy, but worth it IMO We hide abunch of DB-access ugliness behind simple attribute access.Since _get_attr () and _set_attr () are triedbefore DB access is attempted, it's. possible to customizeDB access for individual attributes. for example, if there'sa child table called "Student-classes" that associates acollection of classes with each student, Student._get_classes () could be defined to select and return a list of the student ' SCLASS, AND THENST.CLASES WOULD RETURN The listimization is to cache The cached value.