[Sqlalchemy-commits] [1412] sqlalchemy/branches/schema/doc/build/content: edits
Brought to you by:
zzzeek
From: <co...@sq...> - 2006-05-06 02:14:21
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:':';} #msg dl, #msg dt, #msg ul, #msg li { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[1412] sqlalchemy/branches/schema/doc/build/content: edits</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1412</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-05-05 21:14:06 -0500 (Fri, 05 May 2006)</dd> </dl> <h3>Log Message</h3> <pre>edits</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemybranchesschemadocbuildcontentadv_datamappingtxt">sqlalchemy/branches/schema/doc/build/content/adv_datamapping.txt</a></li> <li><a href="#sqlalchemybranchesschemadocbuildcontentdatamappingtxt">sqlalchemy/branches/schema/doc/build/content/datamapping.txt</a></li> <li><a href="#sqlalchemybranchesschemadocbuildcontentdbenginetxt">sqlalchemy/branches/schema/doc/build/content/dbengine.txt</a></li> <li><a href="#sqlalchemybranchesschemadocbuildcontentmetadatatxt">sqlalchemy/branches/schema/doc/build/content/metadata.txt</a></li> <li><a href="#sqlalchemybranchesschemadocbuildcontentsqlconstructiontxt">sqlalchemy/branches/schema/doc/build/content/sqlconstruction.txt</a></li> <li><a href="#sqlalchemybranchesschemadocbuildcontentunitofworktxt">sqlalchemy/branches/schema/doc/build/content/unitofwork.txt</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemybranchesschemadocbuildcontentadv_datamappingtxt"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/doc/build/content/adv_datamapping.txt (1411 => 1412)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/doc/build/content/adv_datamapping.txt 2006-05-06 00:54:41 UTC (rev 1411) +++ sqlalchemy/branches/schema/doc/build/content/adv_datamapping.txt 2006-05-06 02:14:06 UTC (rev 1412) </span><span class="lines">@@ -363,7 +363,7 @@ </span><span class="cx"> </span><span class="cx"> Without polymorphic loading, you just define a separate mapper for each class. </span><span class="cx"> </span><del>- {python} </del><ins>+ {python title="Concrete Inheritance, Non-polymorphic"} </ins><span class="cx"> managers_table = Table('managers', metadata, </span><span class="cx"> Column('employee_id', Integer, primary_key=True), </span><span class="cx"> Column('name', String(50)), </span><span class="lines">@@ -381,7 +381,7 @@ </span><span class="cx"> </span><span class="cx"> With polymorphic loading, the SQL query to do the actual polymorphic load must be constructed, usually as a UNION. There is a helper function to create these UNIONS called `polymorphic_union`. </span><span class="cx"> </span><del>- {python} </del><ins>+ {python title="Concrete Inheritance, Polymorphic"} </ins><span class="cx"> pjoin = polymorphic_union({ </span><span class="cx"> 'manager':managers_table, </span><span class="cx"> 'engineer':engineers_table </span><span class="lines">@@ -395,7 +395,9 @@ </span><span class="cx"> </span><span class="cx"> #### Multiple Table Inheritance </span><span class="cx"> </span><del>- {python} </del><ins>+Like concrete table inheritance, this can be done non-polymorphically, or with a little more complexity, polymorphically: + + {python title="Multiple Table Inheritance, Non-polymorphic"} </ins><span class="cx"> people = Table('people', metadata, </span><span class="cx"> Column('person_id', Integer, primary_key=True), </span><span class="cx"> Column('name', String(50)), </span><span class="lines">@@ -411,6 +413,13 @@ </span><span class="cx"> Column('manager_data', String(50)), </span><span class="cx"> ) </span><span class="cx"> </span><ins>+ person_mapper = mapper(Person, people) + mapper(Engineer, engineers, inherits=person_mapper) + mapper(Manager, managers, inherits=person_mapper) + +Polymorphic: + + {python title="Multiple Table Inheritance, Polymorphic"} </ins><span class="cx"> person_join = polymorphic_union( </span><span class="cx"> { </span><span class="cx"> 'engineer':people.join(engineers), </span><span class="lines">@@ -422,7 +431,7 @@ </span><span class="cx"> mapper(Engineer, engineers, inherits=person_mapper, polymorphic_identity='engineer') </span><span class="cx"> mapper(Manager, managers, inherits=person_mapper, polymorphic_identity='manager') </span><span class="cx"> </span><del>-The join condition in an inheritance relationship can be specified explicitly, using `inherit_condition`: </del><ins>+The join condition in a multiple table inheritance relationship can be specified explicitly, using `inherit_condition`: </ins><span class="cx"> </span><span class="cx"> {python} </span><span class="cx"> AddressUser.mapper = mapper( </span><span class="lines">@@ -652,11 +661,11 @@ </span><span class="cx"> </span><span class="cx"> Other arguments not covered above include: </span><span class="cx"> </span><del>-* select_table=None - often used with polymorphic mappers, this is a `Selectable` which will take the place of the `Mapper`'s main table argument when performing queries. -* version_id_col=None - an integer-holding Column object that will be assigned an incrementing </del><ins>+* select\_table=None - often used with polymorphic mappers, this is a `Selectable` which will take the place of the `Mapper`'s main table argument when performing queries. +* version\_id\_col=None - an integer-holding Column object that will be assigned an incrementing </ins><span class="cx"> counter, which is added to the WHERE clause used by UPDATE and DELETE statements. The matching row </span><span class="cx"> count returned by the database is compared to the expected row count, and an exception is raised if they dont match. This is a basic "optimistic concurrency" check. Without the version id column, SQLAlchemy still compares the updated rowcount. </span><del>-* always_refresh=False - this option will cause the mapper to refresh all the attributes of all objects loaded by select/get statements, regardless of if they already exist in the current session. this includes all lazy- and eager-loaded relationship attributes, and will also overwrite any changes made to attributes on the column. </del><ins>+* always\_refresh=False - this option will cause the mapper to refresh all the attributes of all objects loaded by select/get statements, regardless of if they already exist in the current session. this includes all lazy- and eager-loaded relationship attributes, and will also overwrite any changes made to attributes on the column. </ins><span class="cx"> </span><span class="cx"> ### Extending Mapper {@name=extending} </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemybranchesschemadocbuildcontentdatamappingtxt"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/doc/build/content/datamapping.txt (1411 => 1412)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/doc/build/content/datamapping.txt 2006-05-06 00:54:41 UTC (rev 1411) +++ sqlalchemy/branches/schema/doc/build/content/datamapping.txt 2006-05-06 02:14:06 UTC (rev 1412) </span><span class="lines">@@ -364,7 +364,7 @@ </span><span class="cx"> </span><span class="cx"> # select users where username is 'jane', get the first element of the list </span><span class="cx"> # this will incur a load operation for the parent table </span><del>- {sql}user = session.query(User).select(user_name='jane')[0] </del><ins>+ {sql}user = session.query(User).select_by(user_name='jane')[0] </ins><span class="cx"> SELECT users.user_id AS users_user_id, </span><span class="cx"> users.user_name AS users_user_name, users.password AS users_password </span><span class="cx"> FROM users WHERE users.user_name = :users_user_name ORDER BY users.oid </span><span class="lines">@@ -378,8 +378,9 @@ </span><span class="cx"> addresses.city AS addresses_city, addresses.state AS addresses_state, </span><span class="cx"> addresses.zip AS addresses_zip FROM addresses </span><span class="cx"> WHERE addresses.user_id = :users_user_id ORDER BY addresses.oid </span><del>- {'users_user_id': 1} - print repr(a) </del><ins>+ {'users_user_id': 1} + + print repr(a) </ins><span class="cx"> </span><span class="cx"> ##### Useful Feature: Creating Joins via select_by {@name=relselectby} </span><span class="cx"> </span><span class="lines">@@ -405,7 +406,7 @@ </span><span class="cx"> </span><span class="cx"> #### Selecting from Relationships: Eager Load {@name=eagerload} </span><span class="cx"> </span><del>-With just a single parameter "lazy=False" specified to the relation object, the parent and child SQL queries can be joined together. </del><ins>+With just a single parameter `lazy=False` specified to the relation object, the parent and child SQL queries can be joined together. </ins><span class="cx"> </span><span class="cx"> {python} </span><span class="cx"> mapper(Address, addresses_table) </span><span class="lines">@@ -447,7 +448,7 @@ </span><span class="cx"> WHERE addresses.street = :addresses_street AND users.user_id = addresses.user_id ORDER BY users.oid, addresses_6ca7.oid </span><span class="cx"> {'addresses_street': '123 Green Street'} </span><span class="cx"> </span><del>-The join implied by passing the "street" parameter is converted into an "aliasized" clause by the eager loader, so that it does not conflict with the join used to eager load the child address objects. </del><ins>+The join implied by passing the "street" parameter is stated as an *additional* join between the `addresses` and `users` tables. Also, since the eager join is "aliasized", no name conflict occurs. </ins><span class="cx"> </span><span class="cx"> #### Switching Lazy/Eager, No Load {@name=options} </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemybranchesschemadocbuildcontentdbenginetxt"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/doc/build/content/dbengine.txt (1411 => 1412)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/doc/build/content/dbengine.txt 2006-05-06 00:54:41 UTC (rev 1411) +++ sqlalchemy/branches/schema/doc/build/content/dbengine.txt 2006-05-06 02:14:06 UTC (rev 1412) </span><span class="lines">@@ -20,14 +20,13 @@ </span><span class="cx"> </span><span class="cx"> ### Supported Databases {@name=supported} </span><span class="cx"> </span><del>-Engines exist for SQLite, Postgres, MySQL, MS-SQL, and Oracle, using the Pysqlite, Psycopg (1 or 2), MySQLDB, adodbapi or pymssql, and cx_Oracle modules. There is also not-well tested support for Firebird. For each engine, a distinct Python module exists in the `sqlalchemy.databases` package, which provides implementations of some of the objects mentioned in the previous section. </del><ins>+Engines exist for SQLite, Postgres, MySQL, and Oracle, using the Pysqlite, Psycopg (1 or 2), MySQLDB, and cx_Oracle modules. There is also preliminary support for MS-SQL using adodbapi or pymssql, as well as Firebird. For each engine, a distinct Python module exists in the `sqlalchemy.databases` package, which provides implementations of some of the objects mentioned in the previous section. </ins><span class="cx"> </span><span class="cx"> ### Establishing a Database Engine {@name=establishing} </span><span class="cx"> </span><span class="cx"> SQLAlchemy 0.2 indicates the source of an Engine strictly via [RFC-1738](http://rfc.net/rfc1738.html) style URLs, combined with optional keyword arguments to specify options for the Engine. The form of the URL is: </span><span class="cx"> </span><del>- {python} - driver://username:password@host:port/database </del><ins>+ $ driver://username:password@host:port/database </ins><span class="cx"> </span><span class="cx"> Available drivernames are `sqlite`, `mysql`, `postgres`, `oracle`, `mssql`, and `firebird`. For sqlite, the database name is the filename to connect to, or the special name ":memory:" which indicates an in-memory database. The URL is typically sent as a string to the `create_engine()` function: </span><span class="cx"> </span><span class="lines">@@ -66,13 +65,13 @@ </span><span class="cx"> * pool_size=5 : the number of connections to keep open inside the connection pool. This is only used with `QueuePool`. </span><span class="cx"> * max_overflow=10 : the number of connections to allow in "overflow", that is connections that can be opened above and beyond the initial five. this is only used with `QueuePool`. </span><span class="cx"> * pool_timeout=30 : number of seconds to wait before giving up on getting a connection from the pool. This is only used with `QueuePool`. </span><del>-* echo=False : if True, the Engine will log all statements as well as a repr() of their parameter lists to the engines logger, which defaults to sys.stdout. A SQLEngine instances' "echo" data member can be modified at any time to turn logging on and off. If set to the string 'debug', result rows will be printed to the standard output as well. -* logger=None : a file-like object where logging output can be sent, if echo is set to True. This defaults to sys.stdout. -* module=None : used by Oracle and Postgres, this is a reference to a DBAPI2 module to be used instead of the engine's default module. For Postgres, the default is psycopg2, or psycopg1 if 2 cannot be found. For Oracle, its cx_Oracle. -* use_ansi=True : used only by Oracle; when False, the Oracle driver attempts to support a particular "quirk" of some Oracle databases, that the LEFT OUTER JOIN SQL syntax is not supported, and the "Oracle join" syntax of using &lt;column1&gt;(+)=&lt;column2&gt; must be used in order to achieve a LEFT OUTER JOIN. Its advised that the Oracle database be configured to have full ANSI support instead of using this feature. -* use_oids=False : used only by Postgres, will enable the column name "oid" as the object ID column. Postgres as of 8.1 has object IDs disabled by default. -* convert_unicode=False : if set to True, all String/character based types will convert Unicode values to raw byte values going into the database, and all raw byte values to Python Unicode coming out in result sets. This is an engine-wide method to provide unicode across the board. For unicode conversion on a column-by-column level, use the Unicode column type instead. -* encoding='utf-8' : the encoding to use for Unicode translations - passed to all encode/decode methods. </del><ins>+* echo=False : if True, the Engine will log all statements as well as a repr() of their parameter lists to the engines logger, which defaults to sys.stdout. The `echo` attribute of `ComposedSQLEngine` can be modified at any time to turn logging on and off. If set to the string `"debug"`, result rows will be printed to the standard output as well. +* logger=None : a file-like object where logging output can be sent, if echo is set to True. Newlines will not be sent with log messages. This defaults to an internal logging object which references `sys.stdout`. +* module=None : used by database implementations which support multiple DBAPI modules, this is a reference to a DBAPI2 module to be used instead of the engine's default module. For Postgres, the default is psycopg2, or psycopg1 if 2 cannot be found. For Oracle, its cx_Oracle. +* use_ansi=True : used only by Oracle; when False, the Oracle driver attempts to support a particular "quirk" of Oracle versions 8 and previous, that the LEFT OUTER JOIN SQL syntax is not supported, and the "Oracle join" syntax of using `&lt;column1&gt;(+)=&lt;column2&gt;` must be used in order to achieve a LEFT OUTER JOIN. +* use_oids=False : used only by Postgres, will enable the column name "oid" as the object ID column, which is also used for the default sort order of tables. Postgres as of 8.1 has object IDs disabled by default. +* convert_unicode=False : if set to True, all String/character based types will convert Unicode values to raw byte values going into the database, and all raw byte values to Python Unicode coming out in result sets. This is an engine-wide method to provide unicode across the board. For unicode conversion on a column-by-column level, use the `Unicode` column type instead. +* encoding='utf-8' : the encoding to use for all Unicode translations, both by engine-wide unicode conversion as well as the `Unicode` type object. </ins><span class="cx"> </span><span class="cx"> ### Using Connections {@name=connections} </span><span class="cx"> </span><span class="lines">@@ -211,7 +210,7 @@ </span><span class="cx"> {python} </span><span class="cx"> # method_a starts a transaction and calls method_b </span><span class="cx"> def method_a(connection): </span><del>- trans = connection.begin() </del><ins>+ trans = connection.begin() # open a transaction </ins><span class="cx"> try: </span><span class="cx"> method_b(connection) </span><span class="cx"> trans.commit() # transaction is committed here </span><span class="lines">@@ -221,7 +220,7 @@ </span><span class="cx"> </span><span class="cx"> # method_b also starts a transaction </span><span class="cx"> def method_b(connection): </span><del>- trans.begin() </del><ins>+ trans = connection.begin() # open a transaction - this runs in the context of method_a's transaction </ins><span class="cx"> try: </span><span class="cx"> connection.execute("insert into mytable values ('bat', 'lala')") </span><span class="cx"> connection.execute(mytable.insert(), col1='bat', col2='lala') </span></span></pre></div> <a id="sqlalchemybranchesschemadocbuildcontentmetadatatxt"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/doc/build/content/metadata.txt (1411 => 1412)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/doc/build/content/metadata.txt 2006-05-06 00:54:41 UTC (rev 1411) +++ sqlalchemy/branches/schema/doc/build/content/metadata.txt 2006-05-06 02:14:06 UTC (rev 1412) </span><span class="lines">@@ -180,27 +180,9 @@ </span><span class="cx"> </span><span class="cx"> ### Creating and Dropping Database Tables {@name=creating} </span><span class="cx"> </span><del>-Creating and dropping individual tables can be done via a `Connection`: </del><ins>+Creating and dropping individual tables can be done via the `create()` and `drop()` methods of `Table`; these methods take an optional `engine` parameter which references an `Engine` or a `Connection`. If not supplied, the `Engine` bound to the `MetaData` will be used, else an error is raised: </ins><span class="cx"> </span><span class="cx"> {python} </span><del>- employees = Table('employees', meta, - Column('employee_id', Integer, primary_key=True), - Column('employee_name', String(60), nullable=False, key='name'), - Column('employee_dept', Integer, ForeignKey("departments.department_id")) - ) - - conn = engine.connect() - {sql}conn.create(employees) - CREATE TABLE employees( - employee_id SERIAL NOT NULL PRIMARY KEY, - employee_name VARCHAR(60) NOT NULL, - employee_dept INTEGER REFERENCES departments(department_id) - ) - {} - -Or off the `create()` method of the `Table` itself; this method takes an optional `engine` parameter which references an `Engine` or a `Connection`. If not supplied, the `Engine` bound to the `MetaData` will be used, else an error is raised: - - {python} </del><span class="cx"> meta = BoundMetaData('sqlite:///:memory:') </span><span class="cx"> employees = Table('employees', meta, </span><span class="cx"> Column('employee_id', Integer, primary_key=True), </span><span class="lines">@@ -215,7 +197,7 @@ </span><span class="cx"> ) </span><span class="cx"> {} </span><span class="cx"> </span><del>-Similarly, both `Connection` and `Table` have a `drop()` method: </del><ins>+`drop()` method: </ins><span class="cx"> </span><span class="cx"> {python} </span><span class="cx"> {sql}employees.drop(engine=e) </span><span class="lines">@@ -335,7 +317,7 @@ </span><span class="cx"> mycolumn datetime default sysdate </span><span class="cx"> ) </span><span class="cx"> </span><del>-PassiveDefaults also send a message to the SQLEngine that data is available after update or insert. The object-relational mapper system uses this information to post-fetch rows after insert or update, so that instances can be refreshed with the new data. Below is a simplified version: </del><ins>+PassiveDefaults also send a message to the `Engine` that data is available after update or insert. The object-relational mapper system uses this information to post-fetch rows after insert or update, so that instances can be refreshed with the new data. Below is a simplified version: </ins><span class="cx"> </span><span class="cx"> {python} </span><span class="cx"> # table with passive defaults </span><span class="lines">@@ -375,7 +357,7 @@ </span><span class="cx"> Column("createdate", DateTime()) </span><span class="cx"> ) </span><span class="cx"> </span><del>-The Sequence is used with Postgres or Oracle to indicate the name of a Sequence that will be used to create default values for a column. When a table with a Sequence on a column is created by SQLAlchemy, the Sequence object is also created. Similarly, the Sequence is dropped when the table is dropped. Sequences are typically used with primary key columns. When using Postgres, if an integer primary key column defines no explicit Sequence or other default method, SQLAlchemy will create the column with the SERIAL keyword, and will pre-execute a sequence named "tablename_columnname_seq" in order to retrieve new primary key values. Oracle, which has no "auto-increment" keyword, requires that a Sequence be created for a table if automatic primary key generation is desired. Note that for all databases, primary key values can always be explicitly stated within the bind parameters for any insert statement as well, removing the need for any kin! d of default generation function. </del><ins>+The Sequence is used with Postgres or Oracle to indicate the name of a database sequence that will be used to create default values for a column. When a table with a Sequence on a column is created in the database by SQLAlchemy, the database sequence object is also created. Similarly, the database sequence is dropped when the table is dropped. Sequences are typically used with primary key columns. When using Postgres, if an integer primary key column defines no explicit Sequence or other default method, SQLAlchemy will create the column with the SERIAL keyword, and will pre-execute a sequence named "tablename_columnname_seq" in order to retrieve new primary key values, if they were not otherwise explicitly stated. Oracle, which has no "auto-increment" keyword, requires that a Sequence be created for a table if automatic primary key generation is desired. </ins><span class="cx"> </span><span class="cx"> A Sequence object can be defined on a Table that is then used for a non-sequence-supporting database. In that case, the Sequence object is simply ignored. Note that a Sequence object is **entirely optional for all databases except Oracle**, as other databases offer options for auto-creating primary key values, such as AUTOINCREMENT, SERIAL, etc. SQLAlchemy will use these default methods for creating primary key values if no Sequence is present on the table metadata. </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemybranchesschemadocbuildcontentsqlconstructiontxt"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/doc/build/content/sqlconstruction.txt (1411 => 1412)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/doc/build/content/sqlconstruction.txt 2006-05-06 00:54:41 UTC (rev 1411) +++ sqlalchemy/branches/schema/doc/build/content/sqlconstruction.txt 2006-05-06 02:14:06 UTC (rev 1412) </span><span class="lines">@@ -1,7 +1,7 @@ </span><span class="cx"> Constructing SQL Queries via Python Expressions {@name=sql} </span><span class="cx"> =============================================== </span><span class="cx"> </span><del>-*Note:* This section describes how to use SQLAlchemy to construct SQL queries and receive result sets. It does *not* cover the object relational mapping capabilities of SQLAlchemy; that is covered later on in [datamapping](rel:datamapping). However, both areas of functionality work similarly in how selection criterion is constructed, so if you are interested just in ORM, you should probably skim through basic [sql_select_whereclause](rel:sql_select_whereclause) construction before moving on. </del><ins>+*Note:* This section describes how to use SQLAlchemy to construct SQL queries and receive result sets. It does *not* cover the object relational mapping capabilities of SQLAlchemy; that is covered later on in [datamapping](rel:datamapping). However, both areas of functionality work similarly in how selection criterion is constructed, so if you are interested just in ORM, you should probably skim through basic [sql_whereclause](rel:sql_whereclause) construction before moving on. </ins><span class="cx"> </span><span class="cx"> Once you have used the `sqlalchemy.schema` module to construct your tables and/or reflect them from the database, performing SQL queries using those table meta data objects is done via the `sqlalchemy.sql` package. This package defines a large set of classes, each of which represents a particular kind of lexical construct within a SQL query; all are descendants of the common base class `sqlalchemy.sql.ClauseElement`. A full query is represented via a structure of `ClauseElement`s. A set of reasonably intuitive creation functions is provided by the `sqlalchemy.sql` package to create these structures; these functions are described in the rest of this section. </span><span class="cx"> </span></span></pre></div> <a id="sqlalchemybranchesschemadocbuildcontentunitofworktxt"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/schema/doc/build/content/unitofwork.txt (1411 => 1412)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/schema/doc/build/content/unitofwork.txt 2006-05-06 00:54:41 UTC (rev 1411) +++ sqlalchemy/branches/schema/doc/build/content/unitofwork.txt 2006-05-06 02:14:06 UTC (rev 1412) </span><span class="lines">@@ -401,20 +401,19 @@ </span><span class="cx"> </span><span class="cx"> The `add()` method will key the `Connection`'s underlying `Engine` to this `SessionTransaction`. When mapper operations are performed against this `Engine`, the `Connection` explicitly added will be used. This **overrides** any other `Connection` objects that the underlying Session was associated with, corresponding to the underlying `Engine` of that `Connection`. However, if the `SessionTransaction` itself is already associated with a `Connection`, then an exception is thrown. </span><span class="cx"> </span><del>-The other way is just to use the `Connection` referenced by the `SessionTransaction`. This is performed via the `connection()` method, and requires passing in a `Mapper` which indicates which underlying `Connection` should be returned. If the `Mapper` argument is `None`, then the `Session` must be globally bound to a specific `Engine` when it was constructed, else the method returns `None`. </del><ins>+The other way is just to use the `Connection` referenced by the `SessionTransaction`. This is performed via the `connection()` method, and requires passing in a class or `Mapper` which indicates which underlying `Connection` should be returned (recall that different `Mappers` may use different underlying `Engines`). If the `class_or_mapper` argument is `None`, then the `Session` must be globally bound to a specific `Engine` when it was constructed, else the method returns `None`. </ins><span class="cx"> </span><span class="cx"> {python title="Get a Connection from the SessionTransaction"} </span><span class="cx"> trans = session.create_transaction() </span><span class="cx"> try: </span><del>- usermapper = session.get_mapper(UserClass) # a convenience method to get a Mapper - connection = trans.connection(usermapper) # get the Connection used by the UserClass' Mapper </del><ins>+ connection = trans.connection(UserClass) # get the Connection used by the UserClass' Mapper </ins><span class="cx"> connection.execute(mytable.update(), {'col1':4, 'col2':17}) </span><span class="cx"> trans.commit() </span><span class="cx"> except: </span><span class="cx"> trans.rollback() </span><span class="cx"> raise </span><span class="cx"> </span><del>-The `connection()` method also exists on the `Session` object itself, and can be called regardless of whether or not a `SessionTransaction` is in progress. If an `Engine` is being used with `threadlocal` strategy, the `Connection` returned will correspond to the connection resources that are bound to the current thread, if any. </del><ins>+The `connection()` method also exists on the `Session` object itself, and can be called regardless of whether or not a `SessionTransaction` is in progress. If a `SessionTransaction` is in progress, it will return the connection referenced by the transaction. If an `Engine` is being used with `threadlocal` strategy, the `Connection` returned will correspond to the connection resources that are bound to the current thread, if any (i.e. it is obtained by calling `contextual_connection()`). </ins><span class="cx"> </span><span class="cx"> #### Using Engine-level Transactions with Sessions </span><span class="cx"> </span></span></pre> </div> </div> </body> </html> |