The examples in this chapter used two tables, one of clients and one of invoices, with a master-detail relationship. In terms of objects, you’d say that a client has a list of related invoices. However, it might be expensive to fetch these every time when a user might want to see them only some of the time.
Let’s implement a lazy fetch to get the
data on demand. This
Customer class inherits from
Record class. Given a database connection, it
fetches its main attributes when explicitly asked, but the invoice
list is retrieved on demand:
class Customer(Record): def __getattr__(self, key): #trap attempts to fetch the list of invoices if key == 'Invoices': self.fetchInvoices() return self.Invoices else: #call the inherited method return Record.__getattr__(self, key) def fetch(self, conn, key): self.conn = conn cursor = self.conn.cursor() cursor.execute("SELECT * FROM Clients \ WHERE ClientID = '%s'" % key) dicts = DataSetFromCursor(cursor).asDicts() assert len(dicts) == 1, 'Error fetching data!' self.loadFromDict(dicts) def fetchInvoices(self): #presumes an attribute pointing to the database cursor = self.conn.cursor() cursor.execute("SELECT * FROM Invoices \ WHERE ClientID = '%s'" % self.ClientID) ds = DataSetFromCursor(cursor) self.Invoices = ds.asObjects()
Using this class is straightforward:
>>> c = laundry.Customer() >>> c.fetch(conn, 'MEGAWAD') # assume an open connection >>> c.CompanyName # see if we got data... 'MegaWad Investments' >>> c.pp() # let's see all ...