sqlobject-cvs Mailing List for SQLObject (Page 74)
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
You can subscribe to this list here.
| 2003 |
Jan
|
Feb
|
Mar
(9) |
Apr
(74) |
May
(29) |
Jun
(16) |
Jul
(28) |
Aug
(10) |
Sep
(57) |
Oct
(9) |
Nov
(29) |
Dec
(12) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2004 |
Jan
(7) |
Feb
(14) |
Mar
(6) |
Apr
(3) |
May
(12) |
Jun
(34) |
Jul
(9) |
Aug
(29) |
Sep
(22) |
Oct
(2) |
Nov
(15) |
Dec
(52) |
| 2005 |
Jan
(47) |
Feb
(78) |
Mar
(14) |
Apr
(35) |
May
(33) |
Jun
(16) |
Jul
(26) |
Aug
(63) |
Sep
(40) |
Oct
(96) |
Nov
(96) |
Dec
(123) |
| 2006 |
Jan
(159) |
Feb
(144) |
Mar
(64) |
Apr
(31) |
May
(88) |
Jun
(48) |
Jul
(16) |
Aug
(64) |
Sep
(87) |
Oct
(92) |
Nov
(56) |
Dec
(76) |
| 2007 |
Jan
(94) |
Feb
(103) |
Mar
(126) |
Apr
(123) |
May
(85) |
Jun
(11) |
Jul
(130) |
Aug
(47) |
Sep
(65) |
Oct
(70) |
Nov
(12) |
Dec
(11) |
| 2008 |
Jan
(30) |
Feb
(55) |
Mar
(88) |
Apr
(20) |
May
(50) |
Jun
|
Jul
(38) |
Aug
(1) |
Sep
(9) |
Oct
(5) |
Nov
(6) |
Dec
(39) |
| 2009 |
Jan
(8) |
Feb
(16) |
Mar
(3) |
Apr
(33) |
May
(44) |
Jun
(1) |
Jul
(10) |
Aug
(33) |
Sep
(74) |
Oct
(22) |
Nov
|
Dec
(15) |
| 2010 |
Jan
(28) |
Feb
(22) |
Mar
(46) |
Apr
(29) |
May
(1) |
Jun
(1) |
Jul
(27) |
Aug
(8) |
Sep
(5) |
Oct
(33) |
Nov
(24) |
Dec
(41) |
| 2011 |
Jan
(4) |
Feb
(12) |
Mar
(35) |
Apr
(29) |
May
(19) |
Jun
(16) |
Jul
(32) |
Aug
(25) |
Sep
(5) |
Oct
(11) |
Nov
(21) |
Dec
(12) |
| 2012 |
Jan
(3) |
Feb
(4) |
Mar
(20) |
Apr
(4) |
May
(25) |
Jun
(13) |
Jul
|
Aug
|
Sep
(2) |
Oct
(25) |
Nov
(9) |
Dec
(1) |
| 2013 |
Jan
(6) |
Feb
(8) |
Mar
|
Apr
(10) |
May
(31) |
Jun
(7) |
Jul
(18) |
Aug
(33) |
Sep
(4) |
Oct
(16) |
Nov
|
Dec
(27) |
| 2014 |
Jan
(2) |
Feb
|
Mar
|
Apr
(11) |
May
(39) |
Jun
(8) |
Jul
(11) |
Aug
(4) |
Sep
|
Oct
(27) |
Nov
|
Dec
(71) |
| 2015 |
Jan
(17) |
Feb
(47) |
Mar
(33) |
Apr
|
May
|
Jun
(9) |
Jul
(7) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(8) |
| 2016 |
Jan
(4) |
Feb
(4) |
Mar
|
Apr
|
May
(12) |
Jun
(7) |
Jul
(9) |
Aug
(31) |
Sep
(8) |
Oct
(3) |
Nov
(15) |
Dec
(1) |
| 2017 |
Jan
(13) |
Feb
(7) |
Mar
(14) |
Apr
(8) |
May
(10) |
Jun
(4) |
Jul
(2) |
Aug
(1) |
Sep
|
Oct
(8) |
Nov
(4) |
Dec
(5) |
| 2018 |
Jan
(2) |
Feb
(8) |
Mar
|
Apr
(4) |
May
|
Jun
(6) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(1) |
Dec
|
| 2019 |
Jan
(1) |
Feb
(16) |
Mar
(1) |
Apr
(3) |
May
(5) |
Jun
(1) |
Jul
|
Aug
|
Sep
(2) |
Oct
|
Nov
(1) |
Dec
(3) |
| 2020 |
Jan
|
Feb
|
Mar
|
Apr
(1) |
May
(1) |
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
(2) |
Nov
|
Dec
(2) |
| 2021 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(1) |
Dec
|
| 2022 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(6) |
Oct
(1) |
Nov
(1) |
Dec
(4) |
| 2023 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
(3) |
Sep
(2) |
Oct
(2) |
Nov
(4) |
Dec
|
| 2024 |
Jan
|
Feb
(2) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(1) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
(9) |
| 2025 |
Jan
|
Feb
(4) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
(2) |
Dec
(2) |
|
From: <sub...@co...> - 2008-02-14 15:18:39
|
Author: phd Date: 2008-02-14 08:18:34 -0700 (Thu, 14 Feb 2008) New Revision: 3256 Modified: SQLObject/tags/0.10.0b2/setup.cfg SQLObject/tags/0.10.0b2/setup.py Log: Version 0.10.0b2. Modified: SQLObject/tags/0.10.0b2/setup.cfg =================================================================== --- SQLObject/tags/0.10.0b2/setup.cfg 2008-02-14 15:16:43 UTC (rev 3255) +++ SQLObject/tags/0.10.0b2/setup.cfg 2008-02-14 15:18:34 UTC (rev 3256) @@ -5,10 +5,6 @@ [easy_install] #find_links = http://svn.pythonpaste.org/package_index.html -[egg_info] -tag_build = dev -tag_svn_revision = true - [pudge] theme = pythonpaste.org docs = docs/index.txt docs/SQLObject.txt docs/TODO.txt Modified: SQLObject/tags/0.10.0b2/setup.py =================================================================== --- SQLObject/tags/0.10.0b2/setup.py 2008-02-14 15:16:43 UTC (rev 3255) +++ SQLObject/tags/0.10.0b2/setup.py 2008-02-14 15:18:34 UTC (rev 3256) @@ -28,7 +28,7 @@ """ setup(name="SQLObject", - version="0.10", + version="0.10.0b2", description="Object-Relational Manager, aka database wrapper", long_description="""\ SQLObject is a popular *Object Relational Manager* for providing an @@ -56,7 +56,7 @@ author="Ian Bicking", author_email="ia...@co...", url="http://sqlobject.org/devel/", - download_url="http://cheeseshop.python.org/pypi/SQLObject/0.10", + download_url="http://cheeseshop.python.org/pypi/SQLObject/0.10.0b2", license="LGPL", packages=["sqlobject"] + ['sqlobject.%s' % package for package in subpackages], scripts=["scripts/sqlobject-admin"], |
|
From: <sub...@co...> - 2008-02-14 15:16:47
|
Author: phd Date: 2008-02-14 08:16:43 -0700 (Thu, 14 Feb 2008) New Revision: 3255 Added: SQLObject/tags/0.10.0b2/ Log: Tagging 0.10.0b2 Copied: SQLObject/tags/0.10.0b2 (from rev 3254, SQLObject/branches/0.10) |
|
From: <sub...@co...> - 2008-02-14 15:16:37
|
Author: phd Date: 2008-02-14 08:16:30 -0700 (Thu, 14 Feb 2008) New Revision: 3254 Modified: SQLObject/branches/0.10/README.txt Log: Version 0.10. Modified: SQLObject/branches/0.10/README.txt =================================================================== --- SQLObject/branches/0.10/README.txt 2008-02-13 20:26:47 UTC (rev 3253) +++ SQLObject/branches/0.10/README.txt 2008-02-14 15:16:30 UTC (rev 3254) @@ -1,5 +1,5 @@ -SQLObject 0.8 -============= +SQLObject 0.10 +============== Thanks for looking at SQLObject. SQLObject is an object-relational mapper, i.e., a library that will wrap your database tables in Python |
|
From: <sub...@co...> - 2008-02-13 20:44:54
|
Author: phd Date: 2008-02-13 13:24:54 -0700 (Wed, 13 Feb 2008) New Revision: 3252 Modified: SQLObject/branches/0.10/README.txt Log: Python 2.3. Modified: SQLObject/branches/0.10/README.txt =================================================================== --- SQLObject/branches/0.10/README.txt 2008-02-13 20:24:01 UTC (rev 3251) +++ SQLObject/branches/0.10/README.txt 2008-02-13 20:24:54 UTC (rev 3252) @@ -7,7 +7,7 @@ It currently supports MySQL through the `MySQLdb` package, PostgreSQL through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB), MS SQL -and Sybase. It should support Python versions back to 2.2. +and Sybase. It should support Python versions back to 2.3. For more information please see the documentation in docs/SQLObject.txt, or online at http://sqlobject.org/ |
|
From: <sub...@co...> - 2008-02-13 20:26:55
|
Author: phd Date: 2008-02-13 13:26:47 -0700 (Wed, 13 Feb 2008) New Revision: 3253 Modified: SQLObject/trunk/README.txt Log: Added MS SQL. Python 2.3. Modified: SQLObject/trunk/README.txt =================================================================== --- SQLObject/trunk/README.txt 2008-02-13 20:24:54 UTC (rev 3252) +++ SQLObject/trunk/README.txt 2008-02-13 20:26:47 UTC (rev 3253) @@ -6,8 +6,8 @@ classes, and your rows in Python instances. It currently supports MySQL through the `MySQLdb` package, PostgreSQL -through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB) and -Sybase. It should support Python versions back to 2.2. +through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB), MS SQL +and Sybase. It should support Python versions back to 2.3. For more information please see the documentation in docs/SQLObject.txt, or online at http://sqlobject.org/ |
|
From: <sub...@co...> - 2008-02-13 20:24:10
|
Author: phd Date: 2008-02-13 13:24:01 -0700 (Wed, 13 Feb 2008) New Revision: 3251 Modified: SQLObject/branches/0.10/README.txt Log: Added MS SQL. Modified: SQLObject/branches/0.10/README.txt =================================================================== --- SQLObject/branches/0.10/README.txt 2008-02-13 20:23:39 UTC (rev 3250) +++ SQLObject/branches/0.10/README.txt 2008-02-13 20:24:01 UTC (rev 3251) @@ -6,8 +6,8 @@ classes, and your rows in Python instances. It currently supports MySQL through the `MySQLdb` package, PostgreSQL -through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB) and -Sybase. It should support Python versions back to 2.2. +through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB), MS SQL +and Sybase. It should support Python versions back to 2.2. For more information please see the documentation in docs/SQLObject.txt, or online at http://sqlobject.org/ |
|
From: <sub...@co...> - 2008-02-13 20:23:51
|
Author: phd Date: 2008-02-13 13:23:39 -0700 (Wed, 13 Feb 2008) New Revision: 3250 Modified: SQLObject/branches/0.9/README.txt Log: Added MS SQL. Modified: SQLObject/branches/0.9/README.txt =================================================================== --- SQLObject/branches/0.9/README.txt 2008-02-13 20:22:47 UTC (rev 3249) +++ SQLObject/branches/0.9/README.txt 2008-02-13 20:23:39 UTC (rev 3250) @@ -6,8 +6,8 @@ classes, and your rows in Python instances. It currently supports MySQL through the `MySQLdb` package, PostgreSQL -through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB) and -Sybase. It should support Python versions back to 2.2. +through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB), MS SQL +and Sybase. It should support Python versions back to 2.2. For more information please see the documentation in docs/SQLObject.txt, or online at http://sqlobject.org/ |
|
From: <sub...@co...> - 2008-02-13 20:22:59
|
Author: phd Date: 2008-02-13 13:22:47 -0700 (Wed, 13 Feb 2008) New Revision: 3249 Modified: SQLObject/branches/0.8/README.txt Log: Added MS SQL. Modified: SQLObject/branches/0.8/README.txt =================================================================== --- SQLObject/branches/0.8/README.txt 2008-02-11 15:20:48 UTC (rev 3248) +++ SQLObject/branches/0.8/README.txt 2008-02-13 20:22:47 UTC (rev 3249) @@ -6,8 +6,8 @@ classes, and your rows in Python instances. It currently supports MySQL through the `MySQLdb` package, PostgreSQL -through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB) and -Sybase. It should support Python versions back to 2.2. +through the `psycopg` package, SQLite, Firebird, MaxDB (SAP DB), MS SQL +and Sybase. It should support Python versions back to 2.2. For more information please see the documentation in docs/SQLObject.txt, or online at http://sqlobject.org/ |
|
From: <sub...@co...> - 2008-02-11 15:21:00
|
Author: phd
Date: 2008-02-11 08:20:48 -0700 (Mon, 11 Feb 2008)
New Revision: 3248
Modified:
SQLObject/trunk/docs/rebuild
Log:
Sort filenames alphabetically.
Modified: SQLObject/trunk/docs/rebuild
===================================================================
--- SQLObject/trunk/docs/rebuild 2008-02-11 15:17:48 UTC (rev 3247)
+++ SQLObject/trunk/docs/rebuild 2008-02-11 15:20:48 UTC (rev 3248)
@@ -6,7 +6,7 @@
export PYTHONPATH=$parent:$PYTHONPATH
NORMAL="Authors DeveloperGuide FAQ Inheritance News News1
- SQLBuilder SQLObject TODO Versioning Views SelectResults
+ SQLBuilder SQLObject SelectResults TODO Versioning Views
web/index web/links web/repository web/community
index community sqlobject-architecture sqlobject-admin"
|
|
From: <sub...@co...> - 2008-02-11 15:17:55
|
Author: phd
Date: 2008-02-11 08:17:48 -0700 (Mon, 11 Feb 2008)
New Revision: 3247
Added:
SQLObject/branches/0.10/docs/SelectResults.txt
SQLObject/branches/0.10/docs/Views.txt
Modified:
SQLObject/branches/0.10/docs/SQLObject.txt
SQLObject/branches/0.10/docs/index.txt
SQLObject/branches/0.10/docs/rebuild
Log:
Merged documentation updates by Luke Opperman from the trunk.
Modified: SQLObject/branches/0.10/docs/SQLObject.txt
===================================================================
--- SQLObject/branches/0.10/docs/SQLObject.txt 2008-02-10 01:07:41 UTC (rev 3246)
+++ SQLObject/branches/0.10/docs/SQLObject.txt 2008-02-11 15:17:48 UTC (rev 3247)
@@ -134,8 +134,8 @@
>>> from sqlobject import *
>>> import sys, os
-Declaring the Class
--------------------
+Declaring a Connection
+----------------------
The connection URI must follow the standard URI syntax::
@@ -180,6 +180,9 @@
The ``sqlhub.processConnection`` assignment means that all classes
will, by default, use this connection we've just set up.
+Declaring the Class
+-------------------
+
We'll develop a simple addressbook-like database. We could create the
tables ourselves, and just have SQLObject access those tables, but
let's have SQLObject do that work. First, the class:
@@ -225,9 +228,11 @@
treat that key as immutable (otherwise you'll confuse SQLObject
terribly).
-You can `override the id name <#idName>`_ in the database, but it is
+You can `override the id name`_ in the database, but it is
always called ``.id`` from Python.
+.. _`override the id name`: `Class sqlmeta`_
+
Using the Class
---------------
@@ -337,9 +342,13 @@
By default SQLObject sends an ``UPDATE`` to the database for every
attribute you set, or every time you call ``.set()``. If you want to
-avoid this many updates, add ``_lazyUpdate = True`` to your class
-definition. Then updates will only be written to the database when
-you call ``inst.syncUpdate()`` or ``obj.sync()``: ``.sync()`` also
+avoid this many updates, add ``lazyUpdate = True`` to your class `sqlmeta
+definition`_.
+
+.. _`sqlmeta definition`: `Class sqlmeta`_
+
+Then updates will only be written to the database when
+you call ``inst.syncUpdate()`` or ``inst.sync()``: ``.sync()`` also
refetches the data from the database, which ``.syncUpdate()`` does not
do.
@@ -417,9 +426,13 @@
.. note::
MultipleJoin, as well as RelatedJoin, returns a list of results.
- Would you prefer to get a SelectResults objects, you should use
- SQLMultipleJoin and SQLRelated Join. Usage stays immutated.
+ It is often preferable to get a `SelectResults`_ object instead,
+ in which case you should use
+ SQLMultipleJoin and SQLRelatedJoin. The declaration of these joins is
+ unchanged from above, but the returned iterator has many additional useful methods.
+.. _`SelectResults` : SelectResults.html
+
Many-to-Many Relationships
--------------------------
@@ -449,11 +462,13 @@
>>> User.createTable()
>>> Role.createTable()
-Note the use of the ``sqlmeta`` class. This class is used to store
-different kinds of metadata (and override that metadata, like
-``table``). This is new in SQLObject 0.7. See the section `Class sqlmeta`_
-for more information on how it works and what attributes have special meanings.
+.. note::
+ The sqlmeta class is used to store
+ different kinds of metadata (and override that metadata, like table).
+ This is new in SQLObject 0.7. See the section `Class sqlmeta`_ for more
+ information on how it works and what attributes have special meanings.
+
And usage::
>>> bob = User(username='bob')
@@ -523,15 +538,15 @@
Selecting Multiple Objects
--------------------------
-While the full power of all the kinds of joins you can do with a
-relational database are not revealed in SQLObject, a simple ``SELECT``
-is available.
+SQLObject allows nearly arbitrary queries, with one overriding caveat:
+the resulting objects must be instances of a SQLObject class.
+``select`` is a class method which usually takes one argument, the equivalent
+to the SQL ``WHERE`` clause. A simple call (with the SQL that's generated)::
-``select`` is a class method, and you call it like (with the SQL
-that's generated)::
-
- >>> Person._connection.debug = True
+ >>> Person._connection.debug = True # to print SQL as it's sent to the database
>>> peeps = Person.select(Person.q.firstName=="John")
+ >>> # Notice that we haven't queried the database yet,
+ >>> # ``peeps`` is an iterable SelectResults instance.
>>> list(peeps)
1/Select : SELECT person.id, person.first_name, person.middle_initial, person.last_name FROM person WHERE (person.first_name = 'John')
1/COMMIT : auto
@@ -568,7 +583,7 @@
.. _orderBy:
-You can use the keyword arguments `orderBy` to create ``ORDER BY`` in the
+You can use the keyword argument `orderBy` to create ``ORDER BY`` in the
select statements: `orderBy` takes a string, which should be the *database*
name of the column, or a column in the form ``Person.q.firstName``. You
can use ``"-colname"`` or ``DESC(Person.q.firstName``) to specify
@@ -576,70 +591,20 @@
types as well), or call ``MyClass.select().reversed()``. orderBy can also
take a list of columns in the same format: ``["-weight", "name"]``.
-You can use the special class variable `_defaultOrder` to give a
+You can use the special `class sqlmeta variable`_ `defaultOrder` to give a
default ordering for all selects. To get an unordered result when
-`_defaultOrder` is used, use ``orderBy=None``.
+`defaultOrder` is used, use ``orderBy=None``.
-Select results are generators, which are lazily evaluated. So the SQL
-is only executed when you iterate over the select results, or if you
-use ``list()`` to force the result to be executed. When you iterate
-over the select results, rows are fetched one at a time. This way you
-can iterate over large results without keeping the entire result set
-in memory. You can also do things like ``.reversed()`` without
-fetching and reversing the entire result -- instead, SQLObject can
-change the SQL that is sent so you get equivalent results.
+.. _`class sqlmeta variable`: `Class sqlmeta`_
-You can also slice select results. This modifies the SQL query, so
-``peeps[:10]`` will result in ``LIMIT 10`` being added to the end of
-the SQL query. If the slice cannot be performed in the SQL (e.g.,
-peeps[:-10]), then the select is executed, and the slice is performed
-on the list of results. This will generally only happen when you use
-negative indexes.
+Select results are generators that allow lazy execution of the underlying
+database query, and further modification of the query before execution.
+Methods are provided for reversing, slicing, ``SELECT DISTINCT``, and ``count``
+and other aggregates. For more information see the `SelectResults`_ documentation.
-In certain cases, you may get a select result with an object in it
-more than once, e.g., in some joins. If you don't want this, you can
-add the keyword argument ``MyClass.select(..., distinct=True)``, which
-results in a ``SELECT DISTINCT`` call.
+For more information on the where clause in the queries see the
+`SQLBuilder`_ documentation.
-You can get the length of the result without fetching all the results
-by calling ``count`` on the result object, like
-``MyClass.select().count()``. A ``COUNT(*)`` query is used -- the
-actual objects are not fetched from the database. Together with
-slicing, this makes batched queries easy to write:
-
- start = 20
- size = 10
- query = Table.select()
- results = query[start:start+size]
- total = query.count()
- print "Showing page %i of %i" % (start/size + 1, total/size + 1)
-
-.. note::
-
- There are several factors when considering the efficiency of this
- kind of batching, and it depends very much how the batching is
- being used. Consider a web application where you are showing an
- average of 100 results, 10 at a time, and the results are ordered
- by the date they were added to the database. While slicing will
- keep the database from returning all the results (and so save some
- communication time), the database will still have to scan through
- the entire result set to sort the items (so it knows which the
- first ten are), and depending on your query may need to scan
- through the entire table (depending on your use of indexes).
- Indexes are probably the most important way to improve importance
- in a case like this, and you may find caching to be more effective
- than slicing.
-
- In this case, caching would mean retrieving the *complete* results.
- You can use ``list(MyClass.select(...))`` to do this. You can save
- these results for some limited period of time, as the user looks
- through the results page by page. This means the first page in a
- search result will be slightly more expensive, but all later pages
- will be very cheap.
-
-For more information on the where clause in the queries, see the
-`SQLBuilder documentation`_.
-
Select-By Method
~~~~~~~~~~~~~~~~
@@ -719,6 +684,9 @@
database will be queried for the table's columns, and any missing
columns (possible all columns) will be added automatically.
+The following attributes provide introspection but should not be set or
+directly - see `Runtime Column and Join Changes`_ for dynamically modifying these class elements.
+
`columns`:
A dictionary of ``{columnName: anSOColInstance}``. You can get
information on the columns via this read-only attribute.
@@ -1180,7 +1148,6 @@
MyTable.select((MyTable.q.name + MyTable.q.surname) == u'value'.encode(dbEncoding))
-.. Relationships_:
Relationships Between Classes/Tables
------------------------------------
@@ -1366,11 +1333,11 @@
One can call as much .commit()'s, but after a .rollback() one has to call
.begin(). The last .commit() should be called as .commit(close=True) to
-release low-level connection.
+release low-level connection back to the connection pool.
You can use SELECT FOR UPDATE in those databases that support it::
- Person.select(Person.q.name=="value", forUpdate=True)
+ Person.select(Person.q.name=="value", forUpdate=True, connection=trans)
Automatic Schema Generation
@@ -1454,32 +1421,35 @@
*This is not supported in SQLite*
-Runtime Column Changes
-----------------------
+Runtime Column and Join Changes
+-------------------------------
*SQLite does not support this feature*
You can add and remove columns to your class at runtime. Such changes
will effect all instances, since changes are made inplace to the
-class. There are two methods, `addColumn` and `delColumn`, both of
+class. There are two methods of the `class sqlmeta object`_,
+`addColumn` and `delColumn`, both of
which take a `Col` object (or subclass) as an argument. There's also
an option argument `changeSchema` which, if True, will add or drop the
column from the database (typically with an ``ALTER`` command).
When adding columns, you must pass the name as part of the column
constructor, like ``StringCol("username", length=20)``. When removing
-columns, you can either use the Col object (as found in `_columns`, or
+columns, you can either use the Col object (as found in `sqlmeta.columns`, or
which you used in `addColumn`), or you can use the column name (like
``MyClass.delColumn("username")``).
+.. _`class sqlmeta object`: `Class sqlmeta`_
+
.. _addJoin:
-You can also add Joins__, like
+You can also add Joins_, like
``MyClass.addJoin(MultipleJoin("MyOtherClass"))``, and remove joins with
`delJoin`. `delJoin` does not take strings, you have to get the join
-object out of the `_joins` attribute.
+object out of the `sqlmeta.joins` attribute.
-__ Relationships_:
+.. _Joins : `Relationships between Classes/Tables`_
Legacy Database Schemas
=======================
@@ -1581,7 +1551,8 @@
convention. For instance::
class Person(SQLObject):
- _style = MixedCaseStyle(longID=True)
+ class sqlmeta:
+ style = MixedCaseStyle(longID=True)
firstName = StringCol()
lastName = StringCol()
@@ -1607,23 +1578,9 @@
Irregular Naming
----------------
-While naming conventions are nice, they are not always present. You
-can control most of the names that SQLObject uses, independent of the
-Python names (so at least you don't have to propagate the
-irregularity to your brand-spanking new Python code).
+This is now covered in the `Class sqlmeta`_ section.
-Here's a simple example::
- class User(SQLObject):
- _table = "user_table"
- _idName = "userid"
-
- username = StringCol(length=20, dbName='name')
-
-The attribute `_table` overrides the table name. `_idName` provides
-an alternative to ``id``. The ``dbName`` keyword argument gives the
-column name.
-
Non-Integer Keys
----------------
@@ -1727,7 +1684,7 @@
column -- strings can go in integer columns, dates in integers, etc.
SQLiteConnection doesn't support `automatic class generation`_ and
-SQLite does not support `runtime column changes`_.
+SQLite does not support `runtime column and join changes`_.
SQLite may have concurrency issues, depending on your usage in a
multi-threaded environment.
Copied: SQLObject/branches/0.10/docs/SelectResults.txt (from rev 3246, SQLObject/trunk/docs/SelectResults.txt)
===================================================================
--- SQLObject/branches/0.10/docs/SelectResults.txt (rev 0)
+++ SQLObject/branches/0.10/docs/SelectResults.txt 2008-02-11 15:17:48 UTC (rev 3247)
@@ -0,0 +1,194 @@
+SelectResults: Using Queries
+============================
+
+.. contents:: Contents:
+
+Overview
+--------
+
+SelectResults are returned from ``.select`` and ``.selectBy`` methods on SQLObject classes, and from ``SQLMultipleJoin``, and ``SQLRelatedJoin`` accessors on SQLObject instances.
+
+Select results are generators, which are lazily evaluated. The SQL
+is only executed when you iterate over the select results, fetching
+rows one at a time. This way you
+can iterate over large results without keeping the entire result set
+in memory. You can also do things like ``.reversed()`` without
+fetching and reversing the entire result -- instead, SQLObject can
+change the SQL that is sent so you get equivalent results.
+
+.. note::
+ To retrieve the results all at once use the python idiom
+ of calling ``list()`` on the generator to force execution
+ and convert the results to a stored list.
+
+You can also slice select results. This modifies the SQL query, so
+``peeps[:10]`` will result in ``LIMIT 10`` being added to the end of
+the SQL query. If the slice cannot be performed in the SQL (e.g.,
+peeps[:-10]), then the select is executed, and the slice is performed
+on the list of results. This will generally only happen when you use
+negative indexes.
+
+In certain cases, you may get a select result with an object in it
+more than once, e.g., in some joins. If you don't want this, you can
+add the keyword argument ``MyClass.select(..., distinct=True)``, which
+results in a ``SELECT DISTINCT`` call.
+
+You can get the length of the result without fetching all the results
+by calling ``count`` on the result object, like
+``MyClass.select().count()``. A ``COUNT(*)`` query is used -- the
+actual objects are not fetched from the database. Together with
+slicing, this makes batched queries easy to write::
+
+ start = 20
+ size = 10
+ query = Table.select()
+ results = query[start:start+size]
+ total = query.count()
+ print "Showing page %i of %i" % (start/size + 1, total/size + 1)
+
+.. note::
+
+ There are several factors when considering the efficiency of this
+ kind of batching, and it depends very much how the batching is
+ being used. Consider a web application where you are showing an
+ average of 100 results, 10 at a time, and the results are ordered
+ by the date they were added to the database. While slicing will
+ keep the database from returning all the results (and so save some
+ communication time), the database will still have to scan through
+ the entire result set to sort the items (so it knows which the
+ first ten are), and depending on your query may need to scan
+ through the entire table (depending on your use of indexes).
+ Indexes are probably the most important way to improve importance
+ in a case like this, and you may find caching to be more effective
+ than slicing.
+
+ In this case, caching would mean retrieving the *complete* results.
+ You can use ``list(MyClass.select(...))`` to do this. You can save
+ these results for some limited period of time, as the user looks
+ through the results page by page. This means the first page in a
+ search result will be slightly more expensive, but all later pages
+ will be very cheap.
+
+Retrieval Methods
+-----------------
+
+Iteration
+~~~~~~~~~
+
+As mentioned in the overview, the typical way to access the results
+is by treating it as a generator and iterating over it (in a loop,
+by converting to a list, etc).
+
+``getOne(default=optional)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In cases where your restrictions cause there to always be a single record
+in the result set, this method will return it or raise an exception:
+SQLObjectIntegrityError if more than one result is found, or
+SQLObjectNotFound if there are actually no results, unless you pass in
+a default like ``.getOne(None)``.
+
+Cloning Methods
+---------------
+
+These methods return a modified copy of the SelectResult instance
+they are called on, so successive calls can chained, eg
+``results = MyClass.selectBy(city='Boston').filter(MyClass.q.commute_distance>10).orderBy('vehicle_mileage')``
+or used independently later on.
+
+
+``orderBy(column)``
+~~~~~~~~~~~~~~~~~~~
+
+Takes a string column name (optionally prefixed with '-' for DESCending)
+or a `SQLBuilder expression`_.
+
+``limit(num)``
+~~~~~~~~~~~~~~
+
+Only return first num many results. Equivalent to results[:num] slicing.
+
+``lazyColumns(v)``
+~~~~~~~~~~~~~~~~~~
+
+Only fetch the IDs for the results, the rest of the columns will be
+retrieved when attributes of the returned instances are accessed.
+
+``reversed()``
+~~~~~~~~~~~~~~
+
+Reverse-order. Alternative to calling orderBy with SQLBuilder.DESC or '-'.
+
+
+``distinct()``
+~~~~~~~~~~~~~~
+
+In SQL, SELECT DISTINCT, removing duplicate rows.
+
+``filter(expression)``
+~~~~~~~~~~~~~~~~~~~~~~
+
+Add additional expressions to restrict result set.
+Takes either a string static SQL expression valid in a WHERE clause,
+or a `SQLBuilder expression`_. ANDed with any previous expressions.
+
+.. _`SQLBuilder expression`: SQLBuilder.html
+
+
+Aggregate Methods
+-----------------
+
+These return column values (strings, numbers, etc)
+not new SQLResults instances, by making the appropriate
+SQL query (the actual result rows are not retrieved).
+Any that take a column can also take a SQLBuilder
+column instance, e.g. ``MyClass.q.size``.
+
+
+``count()``
+~~~~~~~~~~~
+
+Returns the length of the result set, by a SQL ``SELECT COUNT(...)``
+query.
+
+``sum(column)``
+~~~~~~~~~~~~~~~
+
+The sum of values for ``column`` in the result set.
+
+``min(column)``
+~~~~~~~~~~~~~~~
+
+The minimum value for ``column`` in the result set.
+
+``max(column)``
+~~~~~~~~~~~~~~~
+
+The maximum value for ``column`` in the result set.
+
+``avg(column)``
+~~~~~~~~~~~~~~~
+
+The average value for the ``column`` in the result set.
+
+Traversal to related SQLObject classes
+--------------------------------------
+
+``throughTo.join_name and throughTo.foreign_key_name``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This accessor lets you retrieve the objects related to your
+SelectResults by either a join or foreign key relationship,
+in the same manner as the cloning methods above. For instance::
+
+ Schools.select(Schools.q.student_satisfaction>90).throughTo.teachers
+
+returns a SelectResult of Teachers of Schools with satisfied students,
+assuming Schools has a SQLMultipleJoin or SQLRelatedJoin attribute
+named ``teachers``. Similarily, with a self-joining foreign key named
+``father``::
+
+ Person.select(Person.q.name=='Steve').throughTo.father.throughTo.father
+
+returns a SelectResult of Persons who are the paternal grandfather of someone
+named 'Steve'.
\ No newline at end of file
Copied: SQLObject/branches/0.10/docs/Views.txt (from rev 3246, SQLObject/trunk/docs/Views.txt)
===================================================================
--- SQLObject/branches/0.10/docs/Views.txt (rev 0)
+++ SQLObject/branches/0.10/docs/Views.txt 2008-02-11 15:17:48 UTC (rev 3247)
@@ -0,0 +1,64 @@
+Views and SQLObjects
+====================
+
+In general, if your database backend supports defining views
+you may define them outside of SQLObject and treat them
+as a regular table when defining your SQLObject class.
+
+
+ViewSQLObject
+-------------
+
+The rest of this document is experimental.
+
+``from sqlobject.views import *``
+
+``ViewSQLObject`` is an attempt to allow defining
+views that allow you to define a SQL query that acts
+like a SQLObject class. You define columns based on
+other SQLObject classes .q SQLBuilder columns, have columns
+that are aggregates of other columns, and join
+multiple SQLObject classes into one and add restrictions
+using SQLBuilder expressions.
+
+The resulting classes are currently read only, if you find
+use for this idea please bring discussion to the mailing list.
+
+A short example from the tests will suffice for now.
+
+Base classes::
+
+ class PhoneNumber(SQLObject):
+ number = StringCol()
+ calls = SQLMultipleJoin('PhoneCall')
+ incoming = SQLMultipleJoin('PhoneCall', joinColumn='toID')
+
+ class PhoneCall(SQLObject):
+ phoneNumber = ForeignKey('PhoneNumber')
+ to = ForeignKey('PhoneNumber')
+ minutes = IntCol()
+
+View classes::
+
+ class ViewPhoneCall(ViewSQLObject):
+ class sqlmeta:
+ idName = PhoneCall.q.id
+ clause = PhoneCall.q.phoneNumberID==PhoneNumber.q.id
+
+ minutes = IntCol(dbName=PhoneCall.q.minutes)
+ number = StringCol(dbName=PhoneNumber.q.number)
+ phoneNumber = ForeignKey('PhoneNumber', dbName=PhoneNumber.q.id)
+ call = ForeignKey('PhoneCall', dbName=PhoneCall.q.id)
+
+ class ViewPhone(ViewSQLObject):
+ class sqlmeta:
+ idName = PhoneNumber.q.id
+ clause = PhoneCall.q.phoneNumberID==PhoneNumber.q.id
+
+ minutes = IntCol(dbName=func.SUM(PhoneCall.q.minutes))
+ numberOfCalls = IntCol(dbName=func.COUNT(PhoneCall.q.phoneNumberID))
+ number = StringCol(dbName=PhoneNumber.q.number)
+ phoneNumber = ForeignKey('PhoneNumber', dbName=PhoneNumber.q.id)
+ calls = SQLMultipleJoin('PhoneCall', joinColumn='phoneNumberID')
+ vCalls = SQLMultipleJoin('ViewPhoneCall', joinColumn='phoneNumberID')
+
Modified: SQLObject/branches/0.10/docs/index.txt
===================================================================
--- SQLObject/branches/0.10/docs/index.txt 2008-02-10 01:07:41 UTC (rev 3246)
+++ SQLObject/branches/0.10/docs/index.txt 2008-02-11 15:17:48 UTC (rev 3247)
@@ -22,10 +22,12 @@
* `Main SQLObject documentation <SQLObject.html>`_
* `Frequently Asked Questions <FAQ.html>`_
* `sqlbuilder documentation <SQLBuilder.html>`_
+* `select() and SelectResults <SelectResults.html>`_
* `A brief description of SQLObject architecture <sqlobject-architecture.html>`_
* `sqlobject-admin documentation <sqlobject-admin.html>`_
* `Inheritance <Inheritance.html>`_
* `Versioning <Versioning.html>`_
+* `Views <Views.html>`_
* `Developer Guide <DeveloperGuide.html>`_
* `Contributors <Authors.html>`_
Modified: SQLObject/branches/0.10/docs/rebuild
===================================================================
--- SQLObject/branches/0.10/docs/rebuild 2008-02-10 01:07:41 UTC (rev 3246)
+++ SQLObject/branches/0.10/docs/rebuild 2008-02-11 15:17:48 UTC (rev 3247)
@@ -6,7 +6,7 @@
export PYTHONPATH=$parent:$PYTHONPATH
NORMAL="Authors DeveloperGuide FAQ Inheritance News News1
- SQLBuilder SQLObject TODO Versioning
+ SQLBuilder SQLObject SelectResults TODO Versioning Views
web/index web/links web/repository web/community
index community sqlobject-architecture sqlobject-admin"
|
|
From: <sub...@co...> - 2008-02-10 01:07:46
|
Author: luke Date: 2008-02-09 18:07:41 -0700 (Sat, 09 Feb 2008) New Revision: 3246 Modified: SQLObject/trunk/docs/SelectResults.txt Log: Missed definition for lazyColumns, minor style changes. Modified: SQLObject/trunk/docs/SelectResults.txt =================================================================== --- SQLObject/trunk/docs/SelectResults.txt 2008-02-09 05:40:39 UTC (rev 3245) +++ SQLObject/trunk/docs/SelectResults.txt 2008-02-10 01:07:41 UTC (rev 3246) @@ -111,7 +111,8 @@ ``lazyColumns(v)`` ~~~~~~~~~~~~~~~~~~ -?? +Only fetch the IDs for the results, the rest of the columns will be +retrieved when attributes of the returned instances are accessed. ``reversed()`` ~~~~~~~~~~~~~~ @@ -180,14 +181,14 @@ SelectResults by either a join or foreign key relationship, in the same manner as the cloning methods above. For instance:: - ``Schools.select(Schools.q.student_satisfaction>90).throughTo.teachers`` + Schools.select(Schools.q.student_satisfaction>90).throughTo.teachers returns a SelectResult of Teachers of Schools with satisfied students, assuming Schools has a SQLMultipleJoin or SQLRelatedJoin attribute named ``teachers``. Similarily, with a self-joining foreign key named ``father``:: - ``Person.select(Person.q.name=='Steve').throughTo.father.throughTo.father + Person.select(Person.q.name=='Steve').throughTo.father.throughTo.father -returns all those Persons who are the paternal grandfather of someone +returns a SelectResult of Persons who are the paternal grandfather of someone named 'Steve'. \ No newline at end of file |
|
From: <sub...@co...> - 2008-02-09 05:40:44
|
Author: luke
Date: 2008-02-08 22:40:39 -0700 (Fri, 08 Feb 2008)
New Revision: 3245
Added:
SQLObject/trunk/docs/SelectResults.txt
SQLObject/trunk/docs/Views.txt
Modified:
SQLObject/trunk/docs/SQLObject.txt
SQLObject/trunk/docs/index.txt
SQLObject/trunk/docs/rebuild
Log:
Docs update: re-read of the main SQLObject docs, new docs for SelectResults and Views.
Modified: SQLObject/trunk/docs/SQLObject.txt
===================================================================
--- SQLObject/trunk/docs/SQLObject.txt 2008-02-07 15:21:44 UTC (rev 3244)
+++ SQLObject/trunk/docs/SQLObject.txt 2008-02-09 05:40:39 UTC (rev 3245)
@@ -134,8 +134,8 @@
>>> from sqlobject import *
>>> import sys, os
-Declaring the Class
--------------------
+Declaring a Connection
+----------------------
The connection URI must follow the standard URI syntax::
@@ -180,6 +180,9 @@
The ``sqlhub.processConnection`` assignment means that all classes
will, by default, use this connection we've just set up.
+Declaring the Class
+-------------------
+
We'll develop a simple addressbook-like database. We could create the
tables ourselves, and just have SQLObject access those tables, but
let's have SQLObject do that work. First, the class:
@@ -225,9 +228,11 @@
treat that key as immutable (otherwise you'll confuse SQLObject
terribly).
-You can `override the id name <#idName>`_ in the database, but it is
+You can `override the id name`_ in the database, but it is
always called ``.id`` from Python.
+.. _`override the id name`: `Class sqlmeta`_
+
Using the Class
---------------
@@ -337,9 +342,13 @@
By default SQLObject sends an ``UPDATE`` to the database for every
attribute you set, or every time you call ``.set()``. If you want to
-avoid this many updates, add ``_lazyUpdate = True`` to your class
-definition. Then updates will only be written to the database when
-you call ``inst.syncUpdate()`` or ``obj.sync()``: ``.sync()`` also
+avoid this many updates, add ``lazyUpdate = True`` to your class `sqlmeta
+definition`_.
+
+.. _`sqlmeta definition`: `Class sqlmeta`_
+
+Then updates will only be written to the database when
+you call ``inst.syncUpdate()`` or ``inst.sync()``: ``.sync()`` also
refetches the data from the database, which ``.syncUpdate()`` does not
do.
@@ -417,9 +426,13 @@
.. note::
MultipleJoin, as well as RelatedJoin, returns a list of results.
- Would you prefer to get a SelectResults objects, you should use
- SQLMultipleJoin and SQLRelated Join. Usage stays immutated.
+ It is often preferable to get a `SelectResults`_ object instead,
+ in which case you should use
+ SQLMultipleJoin and SQLRelatedJoin. The declaration of these joins is
+ unchanged from above, but the returned iterator has many additional useful methods.
+.. _`SelectResults` : SelectResults.html
+
Many-to-Many Relationships
--------------------------
@@ -449,11 +462,13 @@
>>> User.createTable()
>>> Role.createTable()
-Note the use of the ``sqlmeta`` class. This class is used to store
-different kinds of metadata (and override that metadata, like
-``table``). This is new in SQLObject 0.7. See the section `Class sqlmeta`_
-for more information on how it works and what attributes have special meanings.
+.. note::
+ The sqlmeta class is used to store
+ different kinds of metadata (and override that metadata, like table).
+ This is new in SQLObject 0.7. See the section `Class sqlmeta`_ for more
+ information on how it works and what attributes have special meanings.
+
And usage::
>>> bob = User(username='bob')
@@ -523,15 +538,15 @@
Selecting Multiple Objects
--------------------------
-While the full power of all the kinds of joins you can do with a
-relational database are not revealed in SQLObject, a simple ``SELECT``
-is available.
+SQLObject allows nearly arbitrary queries, with one overriding caveat:
+the resulting objects must be instances of a SQLObject class.
+``select`` is a class method which usually takes one argument, the equivalent
+to the SQL ``WHERE`` clause. A simple call (with the SQL that's generated)::
-``select`` is a class method, and you call it like (with the SQL
-that's generated)::
-
- >>> Person._connection.debug = True
+ >>> Person._connection.debug = True # to print SQL as it's sent to the database
>>> peeps = Person.select(Person.q.firstName=="John")
+ >>> # Notice that we haven't queried the database yet,
+ >>> # ``peeps`` is an iterable SelectResults instance.
>>> list(peeps)
1/Select : SELECT person.id, person.first_name, person.middle_initial, person.last_name FROM person WHERE (person.first_name = 'John')
1/COMMIT : auto
@@ -568,7 +583,7 @@
.. _orderBy:
-You can use the keyword arguments `orderBy` to create ``ORDER BY`` in the
+You can use the keyword argument `orderBy` to create ``ORDER BY`` in the
select statements: `orderBy` takes a string, which should be the *database*
name of the column, or a column in the form ``Person.q.firstName``. You
can use ``"-colname"`` or ``DESC(Person.q.firstName``) to specify
@@ -576,70 +591,20 @@
types as well), or call ``MyClass.select().reversed()``. orderBy can also
take a list of columns in the same format: ``["-weight", "name"]``.
-You can use the special class variable `_defaultOrder` to give a
+You can use the special `class sqlmeta variable`_ `defaultOrder` to give a
default ordering for all selects. To get an unordered result when
-`_defaultOrder` is used, use ``orderBy=None``.
+`defaultOrder` is used, use ``orderBy=None``.
-Select results are generators, which are lazily evaluated. So the SQL
-is only executed when you iterate over the select results, or if you
-use ``list()`` to force the result to be executed. When you iterate
-over the select results, rows are fetched one at a time. This way you
-can iterate over large results without keeping the entire result set
-in memory. You can also do things like ``.reversed()`` without
-fetching and reversing the entire result -- instead, SQLObject can
-change the SQL that is sent so you get equivalent results.
+.. _`class sqlmeta variable`: `Class sqlmeta`_
-You can also slice select results. This modifies the SQL query, so
-``peeps[:10]`` will result in ``LIMIT 10`` being added to the end of
-the SQL query. If the slice cannot be performed in the SQL (e.g.,
-peeps[:-10]), then the select is executed, and the slice is performed
-on the list of results. This will generally only happen when you use
-negative indexes.
+Select results are generators that allow lazy execution of the underlying
+database query, and further modification of the query before execution.
+Methods are provided for reversing, slicing, ``SELECT DISTINCT``, and ``count``
+and other aggregates. For more information see the `SelectResults`_ documentation.
-In certain cases, you may get a select result with an object in it
-more than once, e.g., in some joins. If you don't want this, you can
-add the keyword argument ``MyClass.select(..., distinct=True)``, which
-results in a ``SELECT DISTINCT`` call.
+For more information on the where clause in the queries see the
+`SQLBuilder`_ documentation.
-You can get the length of the result without fetching all the results
-by calling ``count`` on the result object, like
-``MyClass.select().count()``. A ``COUNT(*)`` query is used -- the
-actual objects are not fetched from the database. Together with
-slicing, this makes batched queries easy to write:
-
- start = 20
- size = 10
- query = Table.select()
- results = query[start:start+size]
- total = query.count()
- print "Showing page %i of %i" % (start/size + 1, total/size + 1)
-
-.. note::
-
- There are several factors when considering the efficiency of this
- kind of batching, and it depends very much how the batching is
- being used. Consider a web application where you are showing an
- average of 100 results, 10 at a time, and the results are ordered
- by the date they were added to the database. While slicing will
- keep the database from returning all the results (and so save some
- communication time), the database will still have to scan through
- the entire result set to sort the items (so it knows which the
- first ten are), and depending on your query may need to scan
- through the entire table (depending on your use of indexes).
- Indexes are probably the most important way to improve importance
- in a case like this, and you may find caching to be more effective
- than slicing.
-
- In this case, caching would mean retrieving the *complete* results.
- You can use ``list(MyClass.select(...))`` to do this. You can save
- these results for some limited period of time, as the user looks
- through the results page by page. This means the first page in a
- search result will be slightly more expensive, but all later pages
- will be very cheap.
-
-For more information on the where clause in the queries, see the
-`SQLBuilder documentation`_.
-
Select-By Method
~~~~~~~~~~~~~~~~
@@ -719,6 +684,9 @@
database will be queried for the table's columns, and any missing
columns (possible all columns) will be added automatically.
+The following attributes provide introspection but should not be set or
+directly - see `Runtime Column and Join Changes`_ for dynamically modifying these class elements.
+
`columns`:
A dictionary of ``{columnName: anSOColInstance}``. You can get
information on the columns via this read-only attribute.
@@ -1180,7 +1148,6 @@
MyTable.select((MyTable.q.name + MyTable.q.surname) == u'value'.encode(dbEncoding))
-.. Relationships_:
Relationships Between Classes/Tables
------------------------------------
@@ -1366,11 +1333,11 @@
One can call as much .commit()'s, but after a .rollback() one has to call
.begin(). The last .commit() should be called as .commit(close=True) to
-release low-level connection.
+release low-level connection back to the connection pool.
You can use SELECT FOR UPDATE in those databases that support it::
- Person.select(Person.q.name=="value", forUpdate=True)
+ Person.select(Person.q.name=="value", forUpdate=True, connection=trans)
Automatic Schema Generation
@@ -1454,32 +1421,35 @@
*This is not supported in SQLite*
-Runtime Column Changes
-----------------------
+Runtime Column and Join Changes
+-------------------------------
*SQLite does not support this feature*
You can add and remove columns to your class at runtime. Such changes
will effect all instances, since changes are made inplace to the
-class. There are two methods, `addColumn` and `delColumn`, both of
+class. There are two methods of the `class sqlmeta object`_,
+`addColumn` and `delColumn`, both of
which take a `Col` object (or subclass) as an argument. There's also
an option argument `changeSchema` which, if True, will add or drop the
column from the database (typically with an ``ALTER`` command).
When adding columns, you must pass the name as part of the column
constructor, like ``StringCol("username", length=20)``. When removing
-columns, you can either use the Col object (as found in `_columns`, or
+columns, you can either use the Col object (as found in `sqlmeta.columns`, or
which you used in `addColumn`), or you can use the column name (like
``MyClass.delColumn("username")``).
+.. _`class sqlmeta object`: `Class sqlmeta`_
+
.. _addJoin:
-You can also add Joins__, like
+You can also add Joins_, like
``MyClass.addJoin(MultipleJoin("MyOtherClass"))``, and remove joins with
`delJoin`. `delJoin` does not take strings, you have to get the join
-object out of the `_joins` attribute.
+object out of the `sqlmeta.joins` attribute.
-__ Relationships_:
+.. _Joins : `Relationships between Classes/Tables`_
Legacy Database Schemas
=======================
@@ -1581,7 +1551,8 @@
convention. For instance::
class Person(SQLObject):
- _style = MixedCaseStyle(longID=True)
+ class sqlmeta:
+ style = MixedCaseStyle(longID=True)
firstName = StringCol()
lastName = StringCol()
@@ -1607,23 +1578,9 @@
Irregular Naming
----------------
-While naming conventions are nice, they are not always present. You
-can control most of the names that SQLObject uses, independent of the
-Python names (so at least you don't have to propagate the
-irregularity to your brand-spanking new Python code).
+This is now covered in the `Class sqlmeta`_ section.
-Here's a simple example::
- class User(SQLObject):
- _table = "user_table"
- _idName = "userid"
-
- username = StringCol(length=20, dbName='name')
-
-The attribute `_table` overrides the table name. `_idName` provides
-an alternative to ``id``. The ``dbName`` keyword argument gives the
-column name.
-
Non-Integer Keys
----------------
@@ -1727,7 +1684,7 @@
column -- strings can go in integer columns, dates in integers, etc.
SQLiteConnection doesn't support `automatic class generation`_ and
-SQLite does not support `runtime column changes`_.
+SQLite does not support `runtime column and join changes`_.
SQLite may have concurrency issues, depending on your usage in a
multi-threaded environment.
Added: SQLObject/trunk/docs/SelectResults.txt
===================================================================
--- SQLObject/trunk/docs/SelectResults.txt (rev 0)
+++ SQLObject/trunk/docs/SelectResults.txt 2008-02-09 05:40:39 UTC (rev 3245)
@@ -0,0 +1,193 @@
+SelectResults: Using Queries
+============================
+
+.. contents:: Contents:
+
+Overview
+--------
+
+SelectResults are returned from ``.select`` and ``.selectBy`` methods on SQLObject classes, and from ``SQLMultipleJoin``, and ``SQLRelatedJoin`` accessors on SQLObject instances.
+
+Select results are generators, which are lazily evaluated. The SQL
+is only executed when you iterate over the select results, fetching
+rows one at a time. This way you
+can iterate over large results without keeping the entire result set
+in memory. You can also do things like ``.reversed()`` without
+fetching and reversing the entire result -- instead, SQLObject can
+change the SQL that is sent so you get equivalent results.
+
+.. note::
+ To retrieve the results all at once use the python idiom
+ of calling ``list()`` on the generator to force execution
+ and convert the results to a stored list.
+
+You can also slice select results. This modifies the SQL query, so
+``peeps[:10]`` will result in ``LIMIT 10`` being added to the end of
+the SQL query. If the slice cannot be performed in the SQL (e.g.,
+peeps[:-10]), then the select is executed, and the slice is performed
+on the list of results. This will generally only happen when you use
+negative indexes.
+
+In certain cases, you may get a select result with an object in it
+more than once, e.g., in some joins. If you don't want this, you can
+add the keyword argument ``MyClass.select(..., distinct=True)``, which
+results in a ``SELECT DISTINCT`` call.
+
+You can get the length of the result without fetching all the results
+by calling ``count`` on the result object, like
+``MyClass.select().count()``. A ``COUNT(*)`` query is used -- the
+actual objects are not fetched from the database. Together with
+slicing, this makes batched queries easy to write::
+
+ start = 20
+ size = 10
+ query = Table.select()
+ results = query[start:start+size]
+ total = query.count()
+ print "Showing page %i of %i" % (start/size + 1, total/size + 1)
+
+.. note::
+
+ There are several factors when considering the efficiency of this
+ kind of batching, and it depends very much how the batching is
+ being used. Consider a web application where you are showing an
+ average of 100 results, 10 at a time, and the results are ordered
+ by the date they were added to the database. While slicing will
+ keep the database from returning all the results (and so save some
+ communication time), the database will still have to scan through
+ the entire result set to sort the items (so it knows which the
+ first ten are), and depending on your query may need to scan
+ through the entire table (depending on your use of indexes).
+ Indexes are probably the most important way to improve importance
+ in a case like this, and you may find caching to be more effective
+ than slicing.
+
+ In this case, caching would mean retrieving the *complete* results.
+ You can use ``list(MyClass.select(...))`` to do this. You can save
+ these results for some limited period of time, as the user looks
+ through the results page by page. This means the first page in a
+ search result will be slightly more expensive, but all later pages
+ will be very cheap.
+
+Retrieval Methods
+-----------------
+
+Iteration
+~~~~~~~~~
+
+As mentioned in the overview, the typical way to access the results
+is by treating it as a generator and iterating over it (in a loop,
+by converting to a list, etc).
+
+``getOne(default=optional)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In cases where your restrictions cause there to always be a single record
+in the result set, this method will return it or raise an exception:
+SQLObjectIntegrityError if more than one result is found, or
+SQLObjectNotFound if there are actually no results, unless you pass in
+a default like ``.getOne(None)``.
+
+Cloning Methods
+---------------
+
+These methods return a modified copy of the SelectResult instance
+they are called on, so successive calls can chained, eg
+``results = MyClass.selectBy(city='Boston').filter(MyClass.q.commute_distance>10).orderBy('vehicle_mileage')``
+or used independently later on.
+
+
+``orderBy(column)``
+~~~~~~~~~~~~~~~~~~~
+
+Takes a string column name (optionally prefixed with '-' for DESCending)
+or a `SQLBuilder expression`_.
+
+``limit(num)``
+~~~~~~~~~~~~~~
+
+Only return first num many results. Equivalent to results[:num] slicing.
+
+``lazyColumns(v)``
+~~~~~~~~~~~~~~~~~~
+
+??
+
+``reversed()``
+~~~~~~~~~~~~~~
+
+Reverse-order. Alternative to calling orderBy with SQLBuilder.DESC or '-'.
+
+
+``distinct()``
+~~~~~~~~~~~~~~
+
+In SQL, SELECT DISTINCT, removing duplicate rows.
+
+``filter(expression)``
+~~~~~~~~~~~~~~~~~~~~~~
+
+Add additional expressions to restrict result set.
+Takes either a string static SQL expression valid in a WHERE clause,
+or a `SQLBuilder expression`_. ANDed with any previous expressions.
+
+.. _`SQLBuilder expression`: SQLBuilder.html
+
+
+Aggregate Methods
+-----------------
+
+These return column values (strings, numbers, etc)
+not new SQLResults instances, by making the appropriate
+SQL query (the actual result rows are not retrieved).
+Any that take a column can also take a SQLBuilder
+column instance, e.g. ``MyClass.q.size``.
+
+
+``count()``
+~~~~~~~~~~~
+
+Returns the length of the result set, by a SQL ``SELECT COUNT(...)``
+query.
+
+``sum(column)``
+~~~~~~~~~~~~~~~
+
+The sum of values for ``column`` in the result set.
+
+``min(column)``
+~~~~~~~~~~~~~~~
+
+The minimum value for ``column`` in the result set.
+
+``max(column)``
+~~~~~~~~~~~~~~~
+
+The maximum value for ``column`` in the result set.
+
+``avg(column)``
+~~~~~~~~~~~~~~~
+
+The average value for the ``column`` in the result set.
+
+Traversal to related SQLObject classes
+--------------------------------------
+
+``throughTo.join_name and throughTo.foreign_key_name``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This accessor lets you retrieve the objects related to your
+SelectResults by either a join or foreign key relationship,
+in the same manner as the cloning methods above. For instance::
+
+ ``Schools.select(Schools.q.student_satisfaction>90).throughTo.teachers``
+
+returns a SelectResult of Teachers of Schools with satisfied students,
+assuming Schools has a SQLMultipleJoin or SQLRelatedJoin attribute
+named ``teachers``. Similarily, with a self-joining foreign key named
+``father``::
+
+ ``Person.select(Person.q.name=='Steve').throughTo.father.throughTo.father
+
+returns all those Persons who are the paternal grandfather of someone
+named 'Steve'.
\ No newline at end of file
Added: SQLObject/trunk/docs/Views.txt
===================================================================
--- SQLObject/trunk/docs/Views.txt (rev 0)
+++ SQLObject/trunk/docs/Views.txt 2008-02-09 05:40:39 UTC (rev 3245)
@@ -0,0 +1,64 @@
+Views and SQLObjects
+====================
+
+In general, if your database backend supports defining views
+you may define them outside of SQLObject and treat them
+as a regular table when defining your SQLObject class.
+
+
+ViewSQLObject
+-------------
+
+The rest of this document is experimental.
+
+``from sqlobject.views import *``
+
+``ViewSQLObject`` is an attempt to allow defining
+views that allow you to define a SQL query that acts
+like a SQLObject class. You define columns based on
+other SQLObject classes .q SQLBuilder columns, have columns
+that are aggregates of other columns, and join
+multiple SQLObject classes into one and add restrictions
+using SQLBuilder expressions.
+
+The resulting classes are currently read only, if you find
+use for this idea please bring discussion to the mailing list.
+
+A short example from the tests will suffice for now.
+
+Base classes::
+
+ class PhoneNumber(SQLObject):
+ number = StringCol()
+ calls = SQLMultipleJoin('PhoneCall')
+ incoming = SQLMultipleJoin('PhoneCall', joinColumn='toID')
+
+ class PhoneCall(SQLObject):
+ phoneNumber = ForeignKey('PhoneNumber')
+ to = ForeignKey('PhoneNumber')
+ minutes = IntCol()
+
+View classes::
+
+ class ViewPhoneCall(ViewSQLObject):
+ class sqlmeta:
+ idName = PhoneCall.q.id
+ clause = PhoneCall.q.phoneNumberID==PhoneNumber.q.id
+
+ minutes = IntCol(dbName=PhoneCall.q.minutes)
+ number = StringCol(dbName=PhoneNumber.q.number)
+ phoneNumber = ForeignKey('PhoneNumber', dbName=PhoneNumber.q.id)
+ call = ForeignKey('PhoneCall', dbName=PhoneCall.q.id)
+
+ class ViewPhone(ViewSQLObject):
+ class sqlmeta:
+ idName = PhoneNumber.q.id
+ clause = PhoneCall.q.phoneNumberID==PhoneNumber.q.id
+
+ minutes = IntCol(dbName=func.SUM(PhoneCall.q.minutes))
+ numberOfCalls = IntCol(dbName=func.COUNT(PhoneCall.q.phoneNumberID))
+ number = StringCol(dbName=PhoneNumber.q.number)
+ phoneNumber = ForeignKey('PhoneNumber', dbName=PhoneNumber.q.id)
+ calls = SQLMultipleJoin('PhoneCall', joinColumn='phoneNumberID')
+ vCalls = SQLMultipleJoin('ViewPhoneCall', joinColumn='phoneNumberID')
+
Modified: SQLObject/trunk/docs/index.txt
===================================================================
--- SQLObject/trunk/docs/index.txt 2008-02-07 15:21:44 UTC (rev 3244)
+++ SQLObject/trunk/docs/index.txt 2008-02-09 05:40:39 UTC (rev 3245)
@@ -22,10 +22,12 @@
* `Main SQLObject documentation <SQLObject.html>`_
* `Frequently Asked Questions <FAQ.html>`_
* `sqlbuilder documentation <SQLBuilder.html>`_
+* `select() and SelectResults <SelectResults.html>`_
* `A brief description of SQLObject architecture <sqlobject-architecture.html>`_
* `sqlobject-admin documentation <sqlobject-admin.html>`_
* `Inheritance <Inheritance.html>`_
* `Versioning <Versioning.html>`_
+* `Views <Views.html>`_
* `Developer Guide <DeveloperGuide.html>`_
* `Contributors <Authors.html>`_
Modified: SQLObject/trunk/docs/rebuild
===================================================================
--- SQLObject/trunk/docs/rebuild 2008-02-07 15:21:44 UTC (rev 3244)
+++ SQLObject/trunk/docs/rebuild 2008-02-09 05:40:39 UTC (rev 3245)
@@ -6,7 +6,7 @@
export PYTHONPATH=$parent:$PYTHONPATH
NORMAL="Authors DeveloperGuide FAQ Inheritance News News1
- SQLBuilder SQLObject TODO Versioning
+ SQLBuilder SQLObject TODO Versioning Views SelectResults
web/index web/links web/repository web/community
index community sqlobject-architecture sqlobject-admin"
|
|
From: <sub...@co...> - 2008-02-07 15:21:48
|
Author: phd Date: 2008-02-07 08:21:44 -0700 (Thu, 07 Feb 2008) New Revision: 3244 Modified: SQLObject/trunk/docs/News.txt Log: Minor fix in grammar. Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-02-07 15:21:22 UTC (rev 3243) +++ SQLObject/trunk/docs/News.txt 2008-02-07 15:21:44 UTC (rev 3244) @@ -63,7 +63,7 @@ considered equal is they have the same id; other methods return NotImplemented. -* RowDestroySignal is send on destroying an SQLObject instance; postfunctions +* RowDestroySignal is sent on destroying an SQLObject instance; postfunctions are run after the row has been destroyed. * Changed the implementation type in BoolCol under SQLite from TINYINT to |
|
From: <sub...@co...> - 2008-02-07 15:21:30
|
Author: phd Date: 2008-02-07 08:21:22 -0700 (Thu, 07 Feb 2008) New Revision: 3243 Modified: SQLObject/branches/0.10/docs/News.txt Log: Minor fix in grammar. Modified: SQLObject/branches/0.10/docs/News.txt =================================================================== --- SQLObject/branches/0.10/docs/News.txt 2008-02-07 15:14:55 UTC (rev 3242) +++ SQLObject/branches/0.10/docs/News.txt 2008-02-07 15:21:22 UTC (rev 3243) @@ -63,7 +63,7 @@ considered equal is they have the same id; other methods return NotImplemented. -* RowDestroySignal is send on destroying an SQLObject instance; postfunctions +* RowDestroySignal is sent on destroying an SQLObject instance; postfunctions are run after the row has been destroyed. * Changed the implementation type in BoolCol under SQLite from TINYINT to |
|
From: <sub...@co...> - 2008-02-07 15:14:59
|
Author: phd
Date: 2008-02-07 08:14:55 -0700 (Thu, 07 Feb 2008)
New Revision: 3242
Modified:
SQLObject/trunk/sqlobject/col.py
Log:
Separate type declaration from the length with a space;
this is needed for PySQLite2 because PySQLite2 parses type declaration
as a whole word (SQLObject uses parsed type declarations to prevent PySQLite2
to convert strings to unicode).
Modified: SQLObject/trunk/sqlobject/col.py
===================================================================
--- SQLObject/trunk/sqlobject/col.py 2008-02-07 15:14:12 UTC (rev 3241)
+++ SQLObject/trunk/sqlobject/col.py 2008-02-07 15:14:55 UTC (rev 3242)
@@ -465,7 +465,7 @@
def _sqliteType(self):
self._check_case_sensitive("SQLite")
- return super(SOStringLikeCol, self)._sqliteType()
+ return super(SOStringLikeCol, self)._sqliteType().replace("CHAR(", "CHAR (")
def _sybaseType(self):
self._check_case_sensitive("SYBASE")
@@ -936,7 +936,7 @@
return "VARCHAR(%i) %s" % (length, checkConstraint)
def _sqliteType(self):
- return self._postgresType()
+ return self._postgresType().replace("CHAR(", "CHAR (")
def _sybaseType(self):
return self._postgresType()
|
|
From: <sub...@co...> - 2008-02-07 15:14:21
|
Author: phd
Date: 2008-02-07 08:14:12 -0700 (Thu, 07 Feb 2008)
New Revision: 3241
Modified:
SQLObject/branches/0.10/sqlobject/col.py
Log:
Separate type declaration from the length with a space;
this is needed for PySQLite2 because PySQLite2 parses type declaration
as a whole word (SQLObject uses parsed type declarations to prevent PySQLite2
to convert strings to unicode).
Modified: SQLObject/branches/0.10/sqlobject/col.py
===================================================================
--- SQLObject/branches/0.10/sqlobject/col.py 2008-02-02 17:35:32 UTC (rev 3240)
+++ SQLObject/branches/0.10/sqlobject/col.py 2008-02-07 15:14:12 UTC (rev 3241)
@@ -465,7 +465,7 @@
def _sqliteType(self):
self._check_case_sensitive("SQLite")
- return super(SOStringLikeCol, self)._sqliteType()
+ return super(SOStringLikeCol, self)._sqliteType().replace("CHAR(", "CHAR (")
def _sybaseType(self):
self._check_case_sensitive("SYBASE")
@@ -936,7 +936,7 @@
return "VARCHAR(%i) %s" % (length, checkConstraint)
def _sqliteType(self):
- return self._postgresType()
+ return self._postgresType().replace("CHAR(", "CHAR (")
def _sybaseType(self):
return self._postgresType()
|
|
From: SourceForge.net <no...@so...> - 2008-02-03 18:06:05
|
Bugs item #1885802, was opened at 2008-02-03 18:59 Message generated for change (Comment added) made by tmaas You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1885802&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: General Group: SQLObject release (specify) Status: Open Resolution: None Priority: 5 Private: No Submitted By: Till Maas (tmaas) Assigned to: Nobody/Anonymous (nobody) Summary: SQLObject should determine joinColumn from Class Name Initial Comment: Currently SQLObject determines the joinColumn for MultipleJoin from the name of the table. In the documentation it is recommended to use "user_table" as a table for an class called User. When one now creates another class, e.g. Address that has a ForeignKey from User in a column called "user", one needs to add joinColumn='user_id' to the MultipleJoin definition within the User class, otherwise one only gets a totally strange python traceback, when one tries to access u.addresses. I attached a simple example, that makes it more clear, where the problem here is. I use python-sqlobject-0.9.2-1.fc7 from Fedora. ---------------------------------------------------------------------- >Comment By: Till Maas (tmaas) Date: 2008-02-03 19:06 Message: Logged In: YES user_id=60606 Originator: YES Even better would be, if it was possible to use: addresses = MultipleJoin(Address.user) and then SQLObject would determine by itself whatever the column_id of Address.user is, without the user of SQLObject needing to know how the internalf of SQLObject work. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1885802&group_id=74338 |
|
From: SourceForge.net <no...@so...> - 2008-02-03 17:59:38
|
Bugs item #1885802, was opened at 2008-02-03 18:59 Message generated for change (Tracker Item Submitted) made by Item Submitter You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1885802&group_id=74338 Please note that this message will contain a full copy of the comment thread, including the initial issue submission, for this request, not just the latest update. Category: General Group: SQLObject release (specify) Status: Open Resolution: None Priority: 5 Private: No Submitted By: Till Maas (tmaas) Assigned to: Nobody/Anonymous (nobody) Summary: SQLObject should determine joinColumn from Class Name Initial Comment: Currently SQLObject determines the joinColumn for MultipleJoin from the name of the table. In the documentation it is recommended to use "user_table" as a table for an class called User. When one now creates another class, e.g. Address that has a ForeignKey from User in a column called "user", one needs to add joinColumn='user_id' to the MultipleJoin definition within the User class, otherwise one only gets a totally strange python traceback, when one tries to access u.addresses. I attached a simple example, that makes it more clear, where the problem here is. I use python-sqlobject-0.9.2-1.fc7 from Fedora. ---------------------------------------------------------------------- You can respond by visiting: https://sourceforge.net/tracker/?func=detail&atid=540672&aid=1885802&group_id=74338 |
|
From: <sub...@co...> - 2008-02-01 14:49:08
|
Author: phd
Date: 2008-02-01 07:48:56 -0700 (Fri, 01 Feb 2008)
New Revision: 3239
Modified:
SQLObject/trunk/docs/SQLObject.txt
Log:
cacheValues can be used with transactions.
Modified: SQLObject/trunk/docs/SQLObject.txt
===================================================================
--- SQLObject/trunk/docs/SQLObject.txt 2008-02-01 14:48:39 UTC (rev 3238)
+++ SQLObject/trunk/docs/SQLObject.txt 2008-02-01 14:48:56 UTC (rev 3239)
@@ -706,8 +706,7 @@
object the database will be queried for a value, i.e., a ``SELECT``
will be issued. If you want to handle concurrent access to the
database from multiple processes then this is probably the way to
- do so. You should also use it with transactions_ (it is not
- implied).
+ do so.
`registry`:
Because SQLObject uses strings to relate classes, and these
@@ -1369,16 +1368,6 @@
.begin(). The last .commit() should be called as .commit(close=True) to
release low-level connection.
-If you want to use transactions you should also turn `_cacheValues`
-off, like::
-
- class Person(SQLObject):
- _cacheValue = False
-
-This, though, makes attribute access very slow (SQLObject queries database
-for an every attribute access). If one wants to set `_cacheValue = True`
-one has to synchronize objects between threads herself.
-
You can use SELECT FOR UPDATE in those databases that support it::
Person.select(Person.q.name=="value", forUpdate=True)
|
|
From: <sub...@co...> - 2008-02-01 14:48:47
|
Author: phd
Date: 2008-02-01 07:48:39 -0700 (Fri, 01 Feb 2008)
New Revision: 3238
Modified:
SQLObject/branches/0.10/docs/SQLObject.txt
Log:
cacheValues can be used with transactions.
Modified: SQLObject/branches/0.10/docs/SQLObject.txt
===================================================================
--- SQLObject/branches/0.10/docs/SQLObject.txt 2008-02-01 14:46:26 UTC (rev 3237)
+++ SQLObject/branches/0.10/docs/SQLObject.txt 2008-02-01 14:48:39 UTC (rev 3238)
@@ -706,8 +706,7 @@
object the database will be queried for a value, i.e., a ``SELECT``
will be issued. If you want to handle concurrent access to the
database from multiple processes then this is probably the way to
- do so. You should also use it with transactions_ (it is not
- implied).
+ do so.
`registry`:
Because SQLObject uses strings to relate classes, and these
@@ -1369,16 +1368,6 @@
.begin(). The last .commit() should be called as .commit(close=True) to
release low-level connection.
-If you want to use transactions you should also turn `_cacheValues`
-off, like::
-
- class Person(SQLObject):
- _cacheValue = False
-
-This, though, makes attribute access very slow (SQLObject queries database
-for an every attribute access). If one wants to set `_cacheValue = True`
-one has to synchronize objects between threads herself.
-
You can use SELECT FOR UPDATE in those databases that support it::
Person.select(Person.q.name=="value", forUpdate=True)
|
|
From: <sub...@co...> - 2008-02-01 14:46:34
|
Author: phd
Date: 2008-02-01 07:46:26 -0700 (Fri, 01 Feb 2008)
New Revision: 3237
Modified:
SQLObject/branches/0.9/docs/SQLObject.txt
Log:
cacheValues can be used with transactions.
Modified: SQLObject/branches/0.9/docs/SQLObject.txt
===================================================================
--- SQLObject/branches/0.9/docs/SQLObject.txt 2008-02-01 14:46:06 UTC (rev 3236)
+++ SQLObject/branches/0.9/docs/SQLObject.txt 2008-02-01 14:46:26 UTC (rev 3237)
@@ -706,8 +706,7 @@
object the database will be queried for a value, i.e., a ``SELECT``
will be issued. If you want to handle concurrent access to the
database from multiple processes then this is probably the way to
- do so. You should also use it with transactions_ (it is not
- implied).
+ do so.
`registry`:
Because SQLObject uses strings to relate classes, and these
@@ -1369,16 +1368,6 @@
.begin(). The last .commit() should be called as .commit(close=True) to
release low-level connection.
-If you want to use transactions you should also turn `_cacheValues`
-off, like::
-
- class Person(SQLObject):
- _cacheValue = False
-
-This, though, makes attribute access very slow (SQLObject queries database
-for an every attribute access). If one wants to set `_cacheValue = True`
-one has to synchronize objects between threads herself.
-
You can use SELECT FOR UPDATE in those databases that support it::
Person.select(Person.q.name=="value", forUpdate=True)
|
|
From: <sub...@co...> - 2008-02-01 14:46:16
|
Author: phd Date: 2008-02-01 07:46:06 -0700 (Fri, 01 Feb 2008) New Revision: 3236 Modified: SQLObject/branches/0.9/setup.cfg Log: Fixed links. Modified: SQLObject/branches/0.9/setup.cfg =================================================================== --- SQLObject/branches/0.9/setup.cfg 2008-02-01 14:43:35 UTC (rev 3235) +++ SQLObject/branches/0.9/setup.cfg 2008-02-01 14:46:06 UTC (rev 3236) @@ -21,7 +21,7 @@ modules = sqlobject exclude_modules = sqlobject.tests title = SQLObject -mailing_list_url = http://sqlobject.org/community.html +mailing_list_url = community.html settings = normal_link_color=#039 visited_color=#093 hover_color=#ddf @@ -31,7 +31,7 @@ nav_button_color=#037 nav_border_color=#05f no_about=true - link1=/SQLObject.html Documentation + link1=SQLObject.html Documentation [publish] doc-dir = docs/html |
|
From: <sub...@co...> - 2008-02-01 14:43:45
|
Author: phd
Date: 2008-02-01 07:43:35 -0700 (Fri, 01 Feb 2008)
New Revision: 3235
Modified:
SQLObject/branches/0.8/docs/SQLObject.txt
Log:
cacheValues can be used with transactions.
Modified: SQLObject/branches/0.8/docs/SQLObject.txt
===================================================================
--- SQLObject/branches/0.8/docs/SQLObject.txt 2008-01-30 13:36:16 UTC (rev 3234)
+++ SQLObject/branches/0.8/docs/SQLObject.txt 2008-02-01 14:43:35 UTC (rev 3235)
@@ -705,8 +705,7 @@
object the database will be queried for a value, i.e., a ``SELECT``
will be issued. If you want to handle concurrent access to the
database from multiple processes then this is probably the way to
- do so. You should also use it with transactions_ (it is not
- implied).
+ do so.
`registry`:
Because SQLObject uses strings to relate classes, and these
@@ -1360,16 +1359,6 @@
.begin(). The last .commit() should be called as .commit(close=True) to
release low-level connection.
-If you want to use transactions you should also turn `_cacheValues`
-off, like::
-
- class Person(SQLObject):
- _cacheValue = False
-
-This, though, makes attribute access very slow (SQLObject queries database
-for an every attribute access). If one wants to set `_cacheValue = True`
-one has to synchronize objects between threads herself.
-
You can use SELECT FOR UPDATE in those databases that support it::
Person.select(Person.q.name=="value", forUpdate=True)
|
|
From: <sub...@co...> - 2008-01-30 13:36:23
|
Author: phd
Date: 2008-01-30 06:36:16 -0700 (Wed, 30 Jan 2008)
New Revision: 3234
Modified:
SQLObject/branches/0.10/setup.cfg
Log:
Fixed links.
Modified: SQLObject/branches/0.10/setup.cfg
===================================================================
--- SQLObject/branches/0.10/setup.cfg 2008-01-30 13:35:33 UTC (rev 3233)
+++ SQLObject/branches/0.10/setup.cfg 2008-01-30 13:36:16 UTC (rev 3234)
@@ -22,7 +22,7 @@
exclude_modules = sqlobject.tests
sqlobject.inheritance.tests
title = SQLObject
-mailing_list_url = http://sqlobject.org/community.html
+mailing_list_url = community.html
settings = normal_link_color=#039
visited_color=#093
hover_color=#ddf
@@ -32,7 +32,7 @@
nav_button_color=#037
nav_border_color=#05f
no_about=true
- link1=/SQLObject.html Documentation
+ link1=SQLObject.html Documentation
[publish]
doc-dir = docs/html
|
|
From: <sub...@co...> - 2008-01-30 13:35:42
|
Author: phd Date: 2008-01-30 06:35:33 -0700 (Wed, 30 Jan 2008) New Revision: 3233 Modified: SQLObject/trunk/docs/DeveloperGuide.txt SQLObject/trunk/docs/News.txt SQLObject/trunk/sqlobject/events.py SQLObject/trunk/sqlobject/main.py SQLObject/trunk/sqlobject/tests/test_events.py Log: A patch by Diez B. Roggisch <die...@ar...>: RowDestroySignal is send on destroying an SQLObject instance; postfunctions are run after the row has been destroyed. Modified: SQLObject/trunk/docs/DeveloperGuide.txt =================================================================== --- SQLObject/trunk/docs/DeveloperGuide.txt 2008-01-30 13:33:02 UTC (rev 3232) +++ SQLObject/trunk/docs/DeveloperGuide.txt 2008-01-30 13:35:33 UTC (rev 3233) @@ -149,7 +149,7 @@ its `getting started`_ document for more. .. __: http://codespeak.net/py/current/doc/test.html -.. _getting started: http://codespeak.net/py/current/doc/getting-started.html +.. _getting started: http://codespeak.net/py/dist/test.html#starting-point-py-test-command-line-tool To actually run the test, you have to give it a database to connect to. You do this with the ``TESTDB`` environmental variable (right now @@ -163,7 +163,7 @@ the test module ``tests/test_modulename.py`` -- only modules that start with ``test_`` will be picked up by py.test. -The "framework" for testing is in ``tests/dbtest``. There's a couple +The "framework" for testing is in ``tests/dbtest``. There's a couple of important functions: ``setupClass(soClass)`` creates the tables for the class. It tries to Modified: SQLObject/trunk/docs/News.txt =================================================================== --- SQLObject/trunk/docs/News.txt 2008-01-30 13:33:02 UTC (rev 3232) +++ SQLObject/trunk/docs/News.txt 2008-01-30 13:35:33 UTC (rev 3233) @@ -63,6 +63,9 @@ considered equal is they have the same id; other methods return NotImplemented. +* RowDestroySignal is send on destroying an SQLObject instance; postfunctions + are run after the row has been destroyed. + * Changed the implementation type in BoolCol under SQLite from TINYINT to BOOLEAN and made fromDatabase machinery to recognize it. Modified: SQLObject/trunk/sqlobject/events.py =================================================================== --- SQLObject/trunk/sqlobject/events.py 2008-01-30 13:33:02 UTC (rev 3232) +++ SQLObject/trunk/sqlobject/events.py 2008-01-30 13:35:33 UTC (rev 3233) @@ -97,7 +97,14 @@ class RowDestroySignal(Signal): """ Called before an instance is deleted. Sender is the instance's - class. Arguments are ``(instance)``. You cannot cancel the delete, + class. Arguments are ``(instance, post_funcs)``. + + ``post_funcs`` is a list of callbacks, intended to have + functions appended to it, and are called without arguments. If + any of the post_funcs raises an exception, the deletion is only + affected if this will prevent a commit. + + You cannot cancel the delete, but you can raise an exception (which will probably cancel the delete, but also cause an uncaught exception if not expected). Modified: SQLObject/trunk/sqlobject/main.py =================================================================== --- SQLObject/trunk/sqlobject/main.py 2008-01-30 13:33:02 UTC (rev 3232) +++ SQLObject/trunk/sqlobject/main.py 2008-01-30 13:35:33 UTC (rev 3233) @@ -1464,7 +1464,8 @@ clearTable = classmethod(clearTable) def destroySelf(self): - self.sqlmeta.send(events.RowDestroySignal, self) + post_funcs = [] + self.sqlmeta.send(events.RowDestroySignal, self, post_funcs) # Kills this object. Kills it dead! klass = self.__class__ @@ -1526,6 +1527,9 @@ self._connection._SO_delete(self) self._connection.cache.expire(self.id, self.__class__) + for func in post_funcs: + func() + def delete(cls, id, connection=None): obj = cls.get(id, connection=connection) obj.destroySelf() Modified: SQLObject/trunk/sqlobject/tests/test_events.py =================================================================== --- SQLObject/trunk/sqlobject/tests/test_events.py 2008-01-30 13:33:02 UTC (rev 3232) +++ SQLObject/trunk/sqlobject/tests/test_events.py 2008-01-30 13:35:33 UTC (rev 3233) @@ -41,13 +41,13 @@ assert len(watcher.log) == 2 assert watcher.log[0] == ({'name': 'foo'}, []) -def test_row_destrow(): +def test_row_destroy(): setupClass(EventTester) watcher = make_listen(events.RowDestroySignal) f = EventTester(name='foo') assert not watcher.log f.destroySelf() - assert watcher.log == [(f,)] + assert watcher.log == [(f, [])] def test_row_update(): setupClass(EventTester) |