summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/sqlsoup.py
diff options
context:
space:
mode:
authorJonathan Ellis <jbellis@gmail.com>2007-08-08 03:52:07 +0000
committerJonathan Ellis <jbellis@gmail.com>2007-08-08 03:52:07 +0000
commit4c82b12a12441471b2eb05d64eeb070a1913fc4a (patch)
tree003c836934627e63fc255830c53d96aea0363a36 /lib/sqlalchemy/ext/sqlsoup.py
parent1a225180b5f2ec1a3a7f6c650ac10ab305b2ac9c (diff)
downloadsqlalchemy-4c82b12a12441471b2eb05d64eeb070a1913fc4a.tar.gz
update SS docs to 0.4
Diffstat (limited to 'lib/sqlalchemy/ext/sqlsoup.py')
-rw-r--r--lib/sqlalchemy/ext/sqlsoup.py87
1 files changed, 35 insertions, 52 deletions
diff --git a/lib/sqlalchemy/ext/sqlsoup.py b/lib/sqlalchemy/ext/sqlsoup.py
index 756b5e1e7..731f80a16 100644
--- a/lib/sqlalchemy/ext/sqlsoup.py
+++ b/lib/sqlalchemy/ext/sqlsoup.py
@@ -20,7 +20,7 @@ engine::
>>> from sqlalchemy.ext.sqlsoup import SqlSoup
>>> db = SqlSoup('sqlite:///:memory:')
-or, you can re-use an existing metadata::
+or, you can re-use an existing metadata or engine::
>>> db = SqlSoup(MetaData(e))
@@ -35,14 +35,14 @@ Loading objects
Loading objects is as easy as this::
- >>> users = db.users.select()
+ >>> users = db.users.all()
>>> users.sort()
>>> users
[MappedUsers(name='Joe Student',email='student@example.edu',password='student',classname=None,admin=0), MappedUsers(name='Bhargan Basepair',email='basepair@example.edu',password='basepair',classname=None,admin=1)]
-Of course, letting the database do the sort is better (".c" is short for ".columns")::
+Of course, letting the database do the sort is better::
- >>> db.users.select(order_by=[db.users.c.name])
+ >>> db.users.order_by(db.users.name).all()
[MappedUsers(name='Bhargan Basepair',email='basepair@example.edu',password='basepair',classname=None,admin=1), MappedUsers(name='Joe Student',email='student@example.edu',password='student',classname=None,admin=0)]
Field access is intuitive::
@@ -55,14 +55,15 @@ WHERE clause. Let's also switch the order_by to DESC while we're at
it::
>>> from sqlalchemy import or_, and_, desc
- >>> where = or_(db.users.c.name=='Bhargan Basepair', db.users.c.email=='student@example.edu')
- >>> db.users.select(where, order_by=[desc(db.users.c.name)])
+ >>> where = or_(db.users.name=='Bhargan Basepair', db.users.email=='student@example.edu')
+ >>> db.users.filter(where).order_by(desc(db.users.name)).all()
[MappedUsers(name='Joe Student',email='student@example.edu',password='student',classname=None,admin=0), MappedUsers(name='Bhargan Basepair',email='basepair@example.edu',password='basepair',classname=None,admin=1)]
-You can also use the select...by methods if you're querying on a
-single column. This allows using keyword arguments as column names::
+You can also use .first() (to retrieve only the first object from a query) or
+.one() (like .first when you expect exactly one user -- it will raise an
+exception if more were returned)::
- >>> db.users.selectone_by(name='Bhargan Basepair')
+ >>> db.users.filter(db.users.name=='Bhargan Basepair').one()
MappedUsers(name='Bhargan Basepair',email='basepair@example.edu',password='basepair',classname=None,admin=1)
Since name is the primary key, this is equivalent to
@@ -70,43 +71,22 @@ Since name is the primary key, this is equivalent to
>>> db.users.get('Bhargan Basepair')
MappedUsers(name='Bhargan Basepair',email='basepair@example.edu',password='basepair',classname=None,admin=1)
+This is also equivalent to
-Select variants
----------------
-
-All the SQLAlchemy Query select variants are available. Here's a
-quick summary of these methods:
-
-- ``get(PK)``: load a single object identified by its primary key
- (either a scalar, or a tuple)
-
-- ``select(Clause, **kwargs)``: perform a select restricted by the
- `Clause` argument; returns a list of objects. The most common clause
- argument takes the form ``db.tablename.c.columname == value``. The
- most common optional argument is `order_by`.
-
-- ``select_by(**params)``: select methods ending with ``_by`` allow
- using bare column names (``columname=value``). This feels more
- natural to most Python programmers; the downside is you can't
- specify ``order_by`` or other select options.
-
-- ``selectfirst``, ``selectfirst_by``: returns only the first object
- found; equivalent to ``select(...)[0]`` or ``select_by(...)[0]``,
- except None is returned if no rows are selected.
+ >>> db.users.filter_by(name='Bhargan Basepair').one()
+ MappedUsers(name='Bhargan Basepair',email='basepair@example.edu',password='basepair',classname=None,admin=1)
-- ``selectone``, ``selectone_by``: like ``selectfirst`` or
- ``selectfirst_by``, but raises if less or more than one object is
- selected.
+filter_by is like filter, but takes kwargs instead of full clause expressions.
+This makes it more concise for simple queries like this, but you can't do
+complex queries like the or_ above or non-equality based comparisons this way.
-- ``count``, ``count_by``: returns an integer count of the rows
- selected.
+Full query documentation
+------------------------
-See the SQLAlchemy documentation for details, `datamapping query`__
-for general info and examples, `sql construction`__ for details on
-constructing ``WHERE`` clauses.
+Get, filter, filter_by, order_by, limit, and the rest of the
+query methods are explained in detail in the `SQLAlchemy documentation`__.
-__ http://www.sqlalchemy.org/docs/datamapping.myt#datamapping_query
-__ http://www.sqlalchemy.org/docs/sqlconstruction.myt
+__ http://www.sqlalchemy.org/docs/04/ormtutorial.html#datamapping_querying
Modifying objects
@@ -125,12 +105,12 @@ multiple updates to a single object will be turned into a single
To finish covering the basics, let's insert a new loan, then delete
it::
- >>> book_id = db.books.selectfirst(db.books.c.title=='Regional Variation in Moss').id
+ >>> book_id = db.books.filter_by(title='Regional Variation in Moss').first().id
>>> db.loans.insert(book_id=book_id, user_name=user.name)
MappedLoans(book_id=2,user_name='Bhargan Basepair',loan_date=None)
>>> db.flush()
- >>> loan = db.loans.selectone_by(book_id=2, user_name='Bhargan Basepair')
+ >>> loan = db.loans.filter_by(book_id=2, user_name='Bhargan Basepair').one()
>>> db.delete(loan)
>>> db.flush()
@@ -146,13 +126,13 @@ to the select methods.
>>> db.loans.insert(book_id=book_id, user_name=user.name)
MappedLoans(book_id=2,user_name='Bhargan Basepair',loan_date=None)
>>> db.flush()
- >>> db.loans.delete(db.loans.c.book_id==2)
+ >>> db.loans.delete(db.loans.book_id==2)
You can similarly update multiple rows at once. This will change the
book_id to 1 in all loans whose book_id is 2::
- >>> db.loans.update(db.loans.c.book_id==2, book_id=1)
- >>> db.loans.select_by(db.loans.c.book_id==1)
+ >>> db.loans.update(db.loans.book_id==2, book_id=1)
+ >>> db.loans.filter_by(book_id=1).all()
[MappedLoans(book_id=1,user_name='Joe Student',loan_date=datetime.datetime(2006, 7, 12, 0, 0))]
@@ -169,7 +149,7 @@ uses that as the join condition automatically.
::
>>> join1 = db.join(db.users, db.loans, isouter=True)
- >>> join1.select_by(name='Joe Student')
+ >>> join1.filter_by(name='Joe Student').all()
[MappedJoin(name='Joe Student',email='student@example.edu',password='student',classname=None,admin=0,book_id=1,user_name='Joe Student',loan_date=datetime.datetime(2006, 7, 12, 0, 0))]
If you're unfortunate enough to be using MySQL with the default MyISAM
@@ -177,7 +157,7 @@ storage engine, you'll have to specify the join condition manually,
since MyISAM does not store foreign keys. Here's the same join again,
with the join condition explicitly specified::
- >>> db.join(db.users, db.loans, db.users.c.name==db.loans.c.user_name, isouter=True)
+ >>> db.join(db.users, db.loans, db.users.name==db.loans.user_name, isouter=True)
<class 'sqlalchemy.ext.sqlsoup.MappedJoin'>
You can compose arbitrarily complex joins by combining Join objects
@@ -185,11 +165,12 @@ with tables or other joins. Here we combine our first join with the
books table::
>>> join2 = db.join(join1, db.books)
- >>> join2.select()
+ >>> join2.all()
[MappedJoin(name='Joe Student',email='student@example.edu',password='student',classname=None,admin=0,book_id=1,user_name='Joe Student',loan_date=datetime.datetime(2006, 7, 12, 0, 0),id=1,title='Mustards I Have Known',published_year='1989',authors='Jones')]
If you join tables that have an identical column name, wrap your join
-with `with_labels`, to disambiguate columns with their table name::
+with `with_labels`, to disambiguate columns with their table name
+(.c is short for .columns)::
>>> db.with_labels(join1).c.keys()
[u'users_name', u'users_email', u'users_password', u'users_classname', u'users_admin', u'loans_book_id', u'loans_user_name', u'loans_loan_date']
@@ -237,7 +218,7 @@ PK in the database.)
>>> s = select([b.c.published_year, func.count('*').label('n')], from_obj=[b], group_by=[b.c.published_year])
>>> s = s.alias('years_with_count')
>>> years_with_count = db.map(s, primary_key=[s.c.published_year])
- >>> years_with_count.select_by(published_year='1989')
+ >>> years_with_count.filter_by(published_year='1989').all()
[MappedBooks(published_year='1989',n=1)]
Obviously if we just wanted to get a list of counts associated with
@@ -281,7 +262,7 @@ Boring tests here. Nothing of real expository value.
::
- >>> db.users.select(db.users.c.classname==None, order_by=[db.users.c.name])
+ >>> db.users.filter_by(classname=None).order_by(db.users.name).all()
[MappedUsers(name='Bhargan Basepair',email='basepair+nospam@example.edu',password='basepair',classname=None,admin=1), MappedUsers(name='Joe Student',email='student@example.edu',password='student',classname=None,admin=0)]
>>> db.nopk
@@ -542,5 +523,7 @@ class SqlSoup:
return 'SqlSoup(%r)' % self._metadata
if __name__ == '__main__':
+ import logging
+ logging.basicConfig()
import doctest
doctest.testmod()