Thread: [SQL-CVS] SQLObject/docs FAQ.txt,NONE,1.1
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
From: <ian...@us...> - 2003-08-22 11:28:49
|
Update of /cvsroot/sqlobject/SQLObject/docs In directory sc8-pr-cvs1:/tmp/cvs-serv28975/docs Added Files: FAQ.txt Log Message: Added a FAQ, with requisite examples --- NEW FILE: FAQ.txt --- +++++++++++++ SQLObject FAQ +++++++++++++ .. contents:: How can I do a LEFT JOIN? ------------------------- The short: you can't. You don't need to. That's a relational way of thinking, not an object way of thinking. But it's okay! It's not hard to do the same thing, even if it's not with the same query. For these examples, imagine you have a bunch of customers, with contacts. Not all customers have a contact, some have several. The left join would look like:: SELECT customer.id, customer.first_name, customer.last_name, contact.id, contact.address FROM customer LEFT JOIN contact ON contact.customer_id = customer.id Simple ~~~~~~ .. raw:: html :file: ../examples/snippets/leftjoin-simple.html The effect is the same as the left join -- you get all the customers, and you get all their contacts. The problem, however, is that you will be executing more queries -- a query for each customer to fetch the contacts -- where with the left join you'd only do one query. The actual amount of information returned from the database will be the same. There's a good chance that this won't be significantly slower. I'd advise doing it this way unless you hit an actual performance problem. Efficient ~~~~~~~~~ Lets say you really don't want to do all those queries. Okay, fine: .. raw:: html :file: ../examples/snippets/leftjoin-more.html This way there will only be at most two queries. It's a little more crude, but this is an optimization, and optimizations often look less than pretty. But, say you don't want to get everyone, just some group of people (presumably a large enough group that you still need this optimization): .. raw:: html :file: ../examples/snippets/leftjoin-more-query.html How Does Inheritance Work? -------------------------- SQLObject is not intended to represent every Python inheritance structure in an RDBMS -- rather it is intended to represent RDBMS structures as Python objects. So lots of things you can do in Python you can't do with SQLObject classes. However, some form of inheritance is possible. One way of using this is to create local conventions. Perhaps: .. raw:: html :file: ../examples/snippets/site-sqlobject.html Since SQLObject doesn't have a firm introspection mechanism (at least not yet) the example shows the beginnings of a bit of ad hoc introspection (in this case exposing the ``_columns`` attribute in a more pleasing/public interface). However, this doesn't relate to *database* inheritance at all, since we didn't define any columns. What if we do? .. raw:: html :file: ../examples/snippets/inheritance.html Unfortunately, the resultant schema probably doesn't look like what you might have wanted: .. raw:: html :file: ../examples/snippets/inheritance-schema.html All the columns from ``person`` are just repeated in the ``employee`` table. What's more, an ID for a Person is distinct from an ID for an employee, so for instance you must choose ``ForeignKey("Person")`` or ``ForeignKey("Employee")``, you can't have a foreign key that sometimes refers to one, and sometimes refers to the other. Altogether, not very useful. You probably want a ``person`` table, and then an ``employee`` table with a one-to-one relation between the two. Of course, you can have that, just create the appropriate classes/tables -- but it will appear as two distinct classes, and you'd have to do something like ``Person(1).employee.position``. Of course, you can always create the necessary shortcuts, like: .. raw:: html :file: ../examples/snippets/inheritance-faked.html It's not the most elegant setup, but it's functional and flexible. There are no plans for further support for inheritance (especially since the composition of multiple classes is usually a better solution anyway). Composite/Compound Attributes ----------------------------- A composite attribute is an attribute formed from two columns. For example: .. raw:: html :file: ../examples/snippets/composite-schema.html Now, you'll probably want to deal with one amount/currency value, instead of two columns. SQLObject doesn't directly support this, but it's easy (and encouraged) to do it on your own: .. raw:: html :file: ../examples/snippets/composite.html You'll note we go to some trouble to make sure that ``Price`` is an immutable object. This is important, because if ``Price`` wasn't and someone changed an attribute, the containing ``InvoiceItem`` instance wouldn't detect the change and update the database. (Also, since ``Price`` doesn't subclass ``SQLObject``, we have to be explicit about creating properties) Some people refer to this sort of class as a *Value Object*, that can be used similar to how an integer or string is used. You could also use a mutable composite class: .. raw:: html :file: ../examples/snippets/composite-mutable.html Pretty much a proxy, really, but ``SOCoords`` could contain other logic, could interact with non-SQLObject-based latitude/longitude values, or could be used among several objects that have latitude/longitude columns. |