[Sqlalchemy-commits] sqlalchemy: add a section on many-to-many deletes
Brought to you by:
zzzeek
From: <co...@sq...> - 2012-06-25 20:43:24
|
details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/8b5adc1e004e changeset: 8427:8b5adc1e004e user: Mike Bayer <mi...@zz...> date: Mon Jun 25 16:42:39 2012 -0400 description: add a section on many-to-many deletes Subject: sqlalchemy: add a section on many-to-many deletes details: http://hg.sqlalchemy.org/sqlalchemy/sqlalchemy/rev/7cfa2af602dc changeset: 8428:7cfa2af602dc user: Mike Bayer <mi...@zz...> date: Mon Jun 25 16:42:39 2012 -0400 description: add a section on many-to-many deletes diffstat: .hgtags | 2 + CHANGES | 349 +- doc/build/conf.py | 6 +- doc/build/core/connections.rst | 45 - doc/build/core/tutorial.rst | 4 +- doc/build/core/types.rst | 6 + doc/build/index.rst | 4 +- doc/build/intro.rst | 10 +- doc/build/orm/events.rst | 8 + doc/build/orm/examples.rst | 9 + doc/build/orm/extensions/declarative.rst | 1 - doc/build/orm/extensions/index.rst | 2 +- doc/build/orm/extensions/instrumentation.rst | 23 - doc/build/orm/extensions/sqlsoup.rst | 11 + doc/build/orm/inheritance.rst | 563 +- doc/build/orm/relationships.rst | 56 +- doc/build/orm/tutorial.rst | 4 +- examples/custom_attributes/custom_management.py | 119 +- examples/declarative_reflection/__init__.py | 47 + examples/declarative_reflection/declarative_reflection.py | 98 + examples/inheritance/joined.py | 135 - examples/inheritance/polymorph.py | 125 + lib/sqlalchemy/__init__.py | 22 +- lib/sqlalchemy/connectors/mxodbc.py | 2 +- lib/sqlalchemy/connectors/mysqldb.py | 9 +- lib/sqlalchemy/connectors/pyodbc.py | 4 +- lib/sqlalchemy/connectors/zxJDBC.py | 2 +- lib/sqlalchemy/databases/__init__.py | 22 +- lib/sqlalchemy/dialects/__init__.py | 28 - lib/sqlalchemy/dialects/firebird/base.py | 7 +- lib/sqlalchemy/dialects/informix/base.py | 10 +- lib/sqlalchemy/dialects/mssql/base.py | 63 +- lib/sqlalchemy/dialects/mysql/base.py | 10 +- lib/sqlalchemy/dialects/oracle/base.py | 33 +- lib/sqlalchemy/dialects/oracle/cx_oracle.py | 5 +- lib/sqlalchemy/dialects/postgresql/base.py | 164 +- lib/sqlalchemy/dialects/sqlite/base.py | 132 +- lib/sqlalchemy/engine/__init__.py | 8 - lib/sqlalchemy/engine/base.py | 182 +- lib/sqlalchemy/engine/default.py | 3 - lib/sqlalchemy/engine/reflection.py | 39 +- lib/sqlalchemy/engine/url.py | 57 +- lib/sqlalchemy/event.py | 2 +- lib/sqlalchemy/events.py | 8 +- lib/sqlalchemy/exc.py | 7 - lib/sqlalchemy/ext/associationproxy.py | 8 +- lib/sqlalchemy/ext/declarative.py | 339 +- lib/sqlalchemy/ext/instrumentation.py | 396 -- lib/sqlalchemy/ext/sqlsoup.py | 811 ++++ lib/sqlalchemy/inspection.py | 44 - lib/sqlalchemy/interfaces.py | 2 +- lib/sqlalchemy/log.py | 2 +- lib/sqlalchemy/orm/__init__.py | 97 +- lib/sqlalchemy/orm/attributes.py | 241 +- lib/sqlalchemy/orm/collections.py | 19 +- lib/sqlalchemy/orm/dependency.py | 11 +- lib/sqlalchemy/orm/deprecated_interfaces.py | 2 +- lib/sqlalchemy/orm/descriptor_props.py | 14 +- lib/sqlalchemy/orm/dynamic.py | 33 +- lib/sqlalchemy/orm/evaluator.py | 28 +- lib/sqlalchemy/orm/events.py | 30 +- lib/sqlalchemy/orm/exc.py | 35 +- lib/sqlalchemy/orm/identity.py | 17 +- lib/sqlalchemy/orm/instrumentation.py | 408 +- lib/sqlalchemy/orm/interfaces.py | 289 +- lib/sqlalchemy/orm/loading.py | 537 --- lib/sqlalchemy/orm/mapper.py | 453 ++- lib/sqlalchemy/orm/persistence.py | 271 +- lib/sqlalchemy/orm/properties.py | 778 +++- lib/sqlalchemy/orm/query.py | 1154 ++++-- lib/sqlalchemy/orm/relationships.py | 918 ----- lib/sqlalchemy/orm/scoping.py | 9 +- lib/sqlalchemy/orm/session.py | 300 +- lib/sqlalchemy/orm/shard.py | 15 + lib/sqlalchemy/orm/state.py | 305 +- lib/sqlalchemy/orm/strategies.py | 524 +- lib/sqlalchemy/orm/sync.py | 32 +- lib/sqlalchemy/orm/unitofwork.py | 35 +- lib/sqlalchemy/orm/util.py | 365 +- lib/sqlalchemy/pool.py | 88 +- lib/sqlalchemy/processors.py | 8 +- lib/sqlalchemy/schema.py | 47 +- lib/sqlalchemy/sql/__init__.py | 4 +- lib/sqlalchemy/sql/compiler.py | 110 +- lib/sqlalchemy/sql/expression.py | 148 +- lib/sqlalchemy/sql/functions.py | 8 +- lib/sqlalchemy/sql/operators.py | 7 +- lib/sqlalchemy/sql/util.py | 181 +- lib/sqlalchemy/sql/visitors.py | 14 +- lib/sqlalchemy/types.py | 201 +- lib/sqlalchemy/util/__init__.py | 6 +- lib/sqlalchemy/util/_collections.py | 85 + lib/sqlalchemy/util/compat.py | 12 - lib/sqlalchemy/util/langhelpers.py | 74 +- lib/sqlalchemy/util/queue.py | 49 +- test/aaa_profiling/test_memusage.py | 206 +- test/aaa_profiling/test_orm.py | 8 +- test/aaa_profiling/test_pool.py | 6 +- test/aaa_profiling/test_resultset.py | 8 +- test/aaa_profiling/test_zoomark.py | 3 +- test/base/test_inspect.py | 62 - test/base/test_utils.py | 200 +- test/dialect/test_mssql.py | 11 +- test/dialect/test_oracle.py | 54 +- test/dialect/test_postgresql.py | 170 +- test/dialect/test_sqlite.py | 103 +- test/engine/test_execute.py | 54 - test/engine/test_parseconnect.py | 39 - test/engine/test_pool.py | 97 - test/engine/test_reconnect.py | 27 - test/engine/test_reflection.py | 132 +- test/ext/test_associationproxy.py | 10 +- test/ext/test_declarative.py | 2260 ++++++++++++- test/ext/test_declarative_inheritance.py | 1043 ----- test/ext/test_declarative_mixin.py | 1082 ------ test/ext/test_declarative_reflection.py | 449 -- test/ext/test_extendedattr.py | 485 -- test/ext/test_serializer.py | 28 +- test/ext/test_sqlsoup.py | 447 ++ test/lib/requires.py | 27 +- test/lib/testing.py | 1 + test/orm/_fixtures.py | 45 +- test/orm/inheritance/_poly_fixtures.py | 48 - test/orm/inheritance/test_abc_inheritance.py | 6 +- test/orm/inheritance/test_basic.py | 8 +- test/orm/inheritance/test_polymorphic_rel.py | 184 +- test/orm/inheritance/test_with_poly.py | 113 - test/orm/test_attributes.py | 137 +- test/orm/test_backref_mutations.py | 4 +- test/orm/test_cascade.py | 21 +- test/orm/test_dynamic.py | 20 +- test/orm/test_events.py | 49 +- test/orm/test_extendedattr.py | 325 + test/orm/test_froms.py | 82 +- test/orm/test_inspect.py | 290 - test/orm/test_instrumentation.py | 166 +- test/orm/test_joins.py | 12 +- test/orm/test_legacy_mutable.py | 375 ++ test/orm/test_load_on_fks.py | 51 +- test/orm/test_mapper.py | 10 +- test/orm/test_merge.py | 170 +- test/orm/test_of_type.py | 572 --- test/orm/test_pickled.py | 14 +- test/orm/test_query.py | 149 +- test/orm/test_rel_fn.py | 973 ----- test/orm/test_relationships.py | 759 +-- test/orm/test_session.py | 7 +- test/orm/test_subquery_relations.py | 2 + test/orm/test_transaction.py | 75 +- test/orm/test_unitofwork.py | 11 +- test/orm/test_update_delete.py | 12 - test/perf/orm2010.py | 4 +- test/sql/test_compiler.py | 32 +- test/sql/test_constraints.py | 62 +- test/sql/test_generative.py | 98 +- test/sql/test_query.py | 70 +- test/sql/test_selectable.py | 122 +- 157 files changed, 10410 insertions(+), 13690 deletions(-) diffs (truncated from 32520 to 300 lines): diff -r 57c06c61aa5d -r 7cfa2af602dc .hgtags --- a/.hgtags Mon Jun 25 14:25:36 2012 -0400 +++ b/.hgtags Mon Jun 25 16:42:39 2012 -0400 @@ -87,3 +87,5 @@ 19a7e3a6058878ecc07a40ea563e9cf92110be3a rel_0_7_4 ebe9514a69a4b4ec6209f0e9aa43053ba28d080b rel_0_7_5 d557287431986274a796348750f1c6ce885b196c rel_0_7_6 +faa9d921eb84651e755839072edf7cc929888119 rel_0_7_7 +78b2833fb74f63423a5daa4837364ec1d7b56152 rel_0_7_8 diff -r 57c06c61aa5d -r 7cfa2af602dc CHANGES --- a/CHANGES Mon Jun 25 14:25:36 2012 -0400 +++ b/CHANGES Mon Jun 25 16:42:39 2012 -0400 @@ -3,337 +3,6 @@ ======= CHANGES ======= - -0.8.0b1 -======= -Changes noted below are specific to version 0.8. -For changes that are in both 0.7 and 0.8, see below -underneath "0.7.xx". - -- general - - SQLAlchemy 0.8 now targets Python 2.5 and - above. Python 2.4 is no longer supported. - - - [removed] The "sqlalchemy.exceptions" - synonym for "sqlalchemy.exc" is removed - fully. [ticket:2433] - -- orm - - [removed] The legacy "mutable" system of the - ORM, including the MutableType class as well - as the mutable=True flag on PickleType - and postgresql.ARRAY has been removed. - In-place mutations are detected by the ORM - using the sqlalchemy.ext.mutable extension, - introduced in 0.7. The removal of MutableType - and associated constructs removes a great - deal of complexity from SQLAlchemy's internals. - The approach performed poorly as it would incur - a scan of the full contents of the Session - when in use. [ticket:2442] - - - [moved] The InstrumentationManager interface - and the entire related system of alternate - class implementation is now moved out - to sqlalchemy.ext.instrumentation. This is - a seldom used system that adds significant - complexity and overhead to the mechanics of - class instrumentation. The new architecture - allows it to remain unused until - InstrumentationManager is actually imported, - at which point it is bootstrapped into - the core. - - - [feature] Major rewrite of relationship() - internals now allow join conditions which - include columns pointing to themselves - within composite foreign keys. A new - API for very specialized primaryjoin conditions - is added, allowing conditions based on - SQL functions, CAST, etc. to be handled - by placing the annotation functions - remote() and foreign() inline within the - expression when necessary. Previous recipes - using the semi-private _local_remote_pairs - approach can be upgraded to this new - approach. [ticket:1401] - - - [feature] New standalone function with_polymorphic() - provides the functionality of query.with_polymorphic() - in a standalone form. It can be applied to any - entity within a query, including as the target - of a join in place of the "of_type()" modifier. - [ticket:2333] - - - [feature] The of_type() construct on attributes - now accepts aliased() class constructs as well - as with_polymorphic constructs, and works with - query.join(), any(), has(), and also - eager loaders subqueryload(), joinedload(), - contains_eager() - [ticket:2438] [ticket:1106] - - - [feature] The "deferred declarative - reflection" system has been moved into the - declarative extension itself, using the - new DeferredReflection class. This - class is now tested with both single - and joined table inheritance use cases. - [ticket:2485] - - - [feature] Added new core function "inspect()", - which serves as a generic gateway to - introspection into mappers, objects, - others. The Mapper and InstanceState - objects have been enhanced with a public - API that allows inspection of mapped - attributes, including filters for column-bound - or relationship-bound properties, inspection - of current object state, history of - attributes, etc. [ticket:2208] - - - [feature] Calling rollback() within a - session.begin_nested() will now only expire - those objects that had net changes within the - scope of that transaction, that is objects which - were dirty or were modified on a flush. This - allows the typical use case for begin_nested(), - that of altering a small subset of objects, to - leave in place the data from the larger enclosing - set of objects that weren't modified in - that sub-transaction. [ticket:2452] - - - [feature] Added utility feature - Session.enable_relationship_loading(), - supersedes relationship.load_on_pending. - Both features should be avoided, however. - [ticket:2372] - - - [bug] The "passive" flag on Session.is_modified() - no longer has any effect. is_modified() in - all cases looks only at local in-memory - modified flags and will not emit any - SQL or invoke loader callables/initializers. - [ticket:2320] - - - [bug] The warning emitted when using - delete-orphan cascade with one-to-many - or many-to-many without single-parent=True - is now an error. The ORM - would fail to function subsequent to this - warning in any case. [ticket:2405] - - - [feature] Query now "auto correlates" by - default in the same way as select() does. - Previously, a Query used as a subquery - in another would require the correlate() - method be called explicitly in order to - correlate a table on the inside to the - outside. As always, correlate(None) - disables correlation. [ticket:2179] - - - [feature] The after_attach event is now - emitted after the object is established - in Session.new or Session.identity_map - upon Session.add(), Session.merge(), - etc., so that the object is represented - in these collections when the event - is called. Added before_attach - event to accommodate use cases that - need autoflush w pre-attached object. - [ticket:2464] - - - [removed] Deprecated identifiers removed: - - * allow_null_pks mapper() argument - (use allow_partial_pks) - - * _get_col_to_prop() mapper method - (use get_property_by_column()) - - * dont_load argument to Session.merge() - (use load=True) - - * sqlalchemy.orm.shard module - (use sqlalchemy.ext.horizontal_shard) - -- engine - - [bug] Fixed bug whereby - a disconnect detect + dispose that occurs - when the QueuePool has threads waiting - for connections would leave those - threads waiting for the duration of - the timeout on the old pool. The fix - now notifies those waiters with a special - exception case and has them move onto - the new pool. This fix may or may - not be ported to 0.7. [ticket:2522] - - - [bug] Fixed bug whereby if a database restart - affected multiple connections, each - connection would individually invoke a new - disposal of the pool, even though only - one disposal is needed. [ticket:2522] - - - [feature] Added a new system - for registration of new dialects in-process - without using an entrypoint. See the - docs for "Registering New Dialects". - [ticket:2462] - - - [bug] The names of the columns on the - .c. attribute of a select().apply_labels() - is now based on <tablename>_<colkey> instead - of <tablename>_<colname>, for those columns - that have a distinctly named .key. - [ticket:2397] - - - [feature] Inspector.get_primary_keys() is - deprecated; use Inspector.get_pk_constraint(). - Courtesy Diana Clarke. [ticket:2422] - - - [bug] The autoload_replace flag on Table, - when False, will cause any reflected foreign key - constraints which refer to already-declared - columns to be skipped, assuming that the - in-Python declared column will take over - the task of specifying in-Python ForeignKey - or ForeignKeyConstraint declarations. - - - [bug] The ResultProxy methods inserted_primary_key, - last_updated_params(), last_inserted_params(), - postfetch_cols(), prefetch_cols() all - assert that the given statement is a compiled - construct, and is an insert() or update() - statement as is appropriate, else - raise InvalidRequestError. [ticket:2498] - - - ResultProxy.last_inserted_ids is removed, - replaced by inserted_primary_key. - -- sql - - [feature] The Inspector object can now be - acquired using the new inspect() service, - part of [ticket:2208] - - - [feature] The column_reflect event now - accepts the Inspector object as the first - argument, preceding "table". Code which - uses the 0.7 version of this very new - event will need modification to add the - "inspector" object as the first argument. - [ticket:2418] - - - [feature] The behavior of column targeting - in result sets is now case sensitive by - default. SQLAlchemy for many years would - run a case-insensitive conversion on these values, - probably to alleviate early case sensitivity - issues with dialects like Oracle and - Firebird. These issues have been more cleanly - solved in more modern versions so the performance - hit of calling lower() on identifiers is removed. - The case insensitive comparisons can be re-enabled - by setting "case_insensitive=False" on - create_engine(). [ticket:2423] - - - [feature] The "unconsumed column names" warning emitted - when keys are present in insert.values() or update.values() - that aren't in the target table is now an exception. - [ticket:2415] - - - [feature] Added "MATCH" clause to ForeignKey, - ForeignKeyConstraint, courtesy Ryan Kelly. - [ticket:2502] - - - [feature] Added support for DELETE and UPDATE from - an alias of a table, which would assumedly - be related to itself elsewhere in the query, - courtesy Ryan Kelly. [ticket:2507] - - - [feature] select() features a correlate_except() - method, auto correlates all selectables except those - passed. - - - [bug] All of UniqueConstraint, ForeignKeyConstraint, - CheckConstraint, and PrimaryKeyConstraint will - attach themselves to their parent table automatically - when they refer to a Table-bound Column object directly - (i.e. not just string column name), and refer to - one and only one Table. Prior to 0.8 this behavior - occurred for UniqueConstraint and PrimaryKeyConstraint, - but not ForeignKeyConstraint or CheckConstraint. - [ticket:2410] - - - [bug] column.label(None) now produces an - anonymous label, instead of returning the - column object itself, consistent with the behavior - of label(column, None). [ticket:2168] - -- sqlite - - [feature] the SQLite date and time types - have been overhauled to support a more open - ended format for input and output, using - name based format strings and regexps. A - new argument "microseconds" also provides - the option to omit the "microseconds" - portion of timestamps. Thanks to - Nathan Wright for the work and tests on - this. [ticket:2363] - -- mssql - - [bug] removed legacy behavior whereby - a column comparison to a scalar SELECT via - == would coerce to an IN with the SQL server - dialect. This is implicit - behavior which fails in other scenarios |