PyDO is meant as a way to give ultimate control to the database people (if they want it) when it comes to database access and still be relatively easy to use, but not as easy as SDS was.
PyDO is also easy to configure, easy to see what goes on under the hood and extremely lightweight (the PyDO.py file comes in currently at 616 lines of not-very-dense code). Because the mapping is quite thin, it is easy to explain how the mythical python expression:
SELECT COL1, COL2, COL3, FOO from TABLE where FOO = :p1
with :p1 being bound to the integer 3 given it's definition.
Not only that, but you can override the way fetches and/or mutations are done so that they don't necessarily even yeild SQL queries, in the case that you want to do stored procedure access. In general, if you want to go direct to the database connection level to do something, you can, and PyDO doesn't care, very much unlike SDS which potentially could get very confused.
PyDO has no notion of a relation. Relations are handled by the PyDO data developer by using methods. For example, if you have a Users class and a Groups class, one would likely write a getGroups() method on the Users object to fetch the Groups object associated with it. PyDO does however provide convience functions to make implementing relations simpler, specifically joinTable and joinTableSQL methods which make many-to-many relations easier. One-to-one and one-to-many are are typically done making calls to getUnique() and getSome() methods on the target class.
Unlike SDS, PyDO can also use more than one connection at a time. Each data class defines a connection alias, which maps to a PyDO connection string which subsequently maps to a database interface instance (specific to the database type). The connection alias feature exists because you don't want to have to change all the connect strings in your code to move them from the development environment to the production environment, you just have to change the connect string that the alias points to.