From 3d10187bd3180ec32ba7f329fc3bcff725d2ef79 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Mon, 1 Jan 2007 00:10:37 +0000 Subject: [PATCH] - global "insure"->"ensure" change. in US english "insure" is actually largely interchangeable with "ensure" (so says the dictionary), so I'm not completely illiterate, but its definitely sub-optimal to "ensure" which is non-ambiguous. --- CHANGES | 4 ++++ doc/build/content/adv_datamapping.txt | 2 +- doc/build/content/datamapping.txt | 4 ++-- doc/build/content/tutorial.txt | 2 +- doc/build/content/unitofwork.txt | 4 ++-- lib/sqlalchemy/ansisql.py | 2 +- lib/sqlalchemy/orm/dependency.py | 2 +- lib/sqlalchemy/orm/mapper.py | 2 +- lib/sqlalchemy/orm/query.py | 4 ++-- lib/sqlalchemy/orm/unitofwork.py | 2 +- 10 files changed, 16 insertions(+), 12 deletions(-) diff --git a/CHANGES b/CHANGES index 57a763b99a..40db6d62ee 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,10 @@ is constructed with individual calls to append_column(); this fixes an ORM bug whereby nested select statements were not getting correlated with the main select generated by the Query object. - speed enhancements to ORM object instantiation, eager loading of rows +- global "insure"->"ensure" change. in US english "insure" is actually +largely interchangeable with "ensure" (so says the dictionary), so I'm not +completely illiterate, but its definitely sub-optimal to "ensure" which is +non-ambiguous. 0.3.3 - string-based FROM clauses fixed, i.e. select(..., from_obj=["sometext"]) diff --git a/doc/build/content/adv_datamapping.txt b/doc/build/content/adv_datamapping.txt index 79f8158a25..0704ee699f 100644 --- a/doc/build/content/adv_datamapping.txt +++ b/doc/build/content/adv_datamapping.txt @@ -253,7 +253,7 @@ Deferred columns can be placed into groups so that they load together: #### Working with Large Collections -SQLAlchemy relations are generally simplistic; the lazy loader loads in the full list of child objects when accessed, and the eager load builds a query that loads the full list of child objects. Additionally, when you are deleting a parent object, SQLAlchemy insures that it has loaded the full list of child objects so that it can mark them as deleted as well (or to update their parent foreign key to NULL). It does not issue an en-masse "delete from table where parent_id=?" type of statement in such a scenario. This is because the child objects themselves may also have further dependencies, and additionally may also exist in the current session in which case SA needs to know their identity so that their state can be properly updated. +SQLAlchemy relations are generally simplistic; the lazy loader loads in the full list of child objects when accessed, and the eager load builds a query that loads the full list of child objects. Additionally, when you are deleting a parent object, SQLAlchemy ensures that it has loaded the full list of child objects so that it can mark them as deleted as well (or to update their parent foreign key to NULL). It does not issue an en-masse "delete from table where parent_id=?" type of statement in such a scenario. This is because the child objects themselves may also have further dependencies, and additionally may also exist in the current session in which case SA needs to know their identity so that their state can be properly updated. So there are several techniques that can be used individually or combined together to address these issues, in the context of a large collection where you normally would not want to load the full list of relationships: diff --git a/doc/build/content/datamapping.txt b/doc/build/content/datamapping.txt index 6b872c36fb..76937c87d1 100644 --- a/doc/build/content/datamapping.txt +++ b/doc/build/content/datamapping.txt @@ -132,7 +132,7 @@ Some of the above examples above illustrate the usage of the mapper's Table obje ### Saving Objects {@name=saving} -When objects corresponding to mapped classes are created or manipulated, all changes are logged by the `Session` object. The changes are then written to the database when an application calls `flush()`. This pattern is known as a *Unit of Work*, and has many advantages over saving individual objects or attributes on those objects with individual method invocations. Domain models can be built with far greater complexity with no concern over the order of saves and deletes, excessive database round-trips and write operations, or deadlocking issues. The `flush()` operation batches its SQL statements into a transaction, and can also perform optimistic concurrency checks (using a version id column) to insure the proper number of rows were in fact affected (not supported with the current MySQL drivers). +When objects corresponding to mapped classes are created or manipulated, all changes are logged by the `Session` object. The changes are then written to the database when an application calls `flush()`. This pattern is known as a *Unit of Work*, and has many advantages over saving individual objects or attributes on those objects with individual method invocations. Domain models can be built with far greater complexity with no concern over the order of saves and deletes, excessive database round-trips and write operations, or deadlocking issues. The `flush()` operation batches its SQL statements into a transaction, and can also perform optimistic concurrency checks (using a version id column) to ensure the proper number of rows were in fact affected (not supported with the current MySQL drivers). The Unit of Work is a powerful tool, and has some important concepts that should be understood in order to use it effectively. See the [unitofwork](rel:unitofwork) section for a full description on all its operations. @@ -754,7 +754,7 @@ The `relation` function handles a basic many-to-many relationship when you speci ### Association Object {@name=association} -Many to Many can also be done with an association object, that adds additional information about how two items are related. In this pattern, the "secondary" option to `relation()` is no longer used; instead, the association object becomes a mapped entity itself, mapped to the association table. If the association table has no explicit primary key columns defined, you also have to tell the mapper what columns will compose its "primary key", which are typically the two (or more) columns involved in the association. Also, the relation between the parent and association mapping is typically set up with a cascade of `all, delete-orphan`. This is to insure that when an association object is removed from its parent collection, it is deleted (otherwise, the unit of work tries to null out one of the foreign key columns, which raises an error condition since that column is also part of its "primary key"). +Many to Many can also be done with an association object, that adds additional information about how two items are related. In this pattern, the "secondary" option to `relation()` is no longer used; instead, the association object becomes a mapped entity itself, mapped to the association table. If the association table has no explicit primary key columns defined, you also have to tell the mapper what columns will compose its "primary key", which are typically the two (or more) columns involved in the association. Also, the relation between the parent and association mapping is typically set up with a cascade of `all, delete-orphan`. This is to ensure that when an association object is removed from its parent collection, it is deleted (otherwise, the unit of work tries to null out one of the foreign key columns, which raises an error condition since that column is also part of its "primary key"). {python} from sqlalchemy import * diff --git a/doc/build/content/tutorial.txt b/doc/build/content/tutorial.txt index 2cce781ea6..291c6ed94c 100644 --- a/doc/build/content/tutorial.txt +++ b/doc/build/content/tutorial.txt @@ -446,7 +446,7 @@ Main documentation for using mappers: [datamapping](rel:datamapping) ### Transactions -You may have noticed from the example above that when we say `session.flush()`, SQLAlchemy indicates the names `BEGIN` and `COMMIT` to indicate a transaction with the database. The `flush()` method, since it may execute many statements in a row, will automatically use a transaction in order to execute these instructions. But what if we want to use `flush()` inside of a larger transaction? This is performed via the `SessionTransaction` object, which we can establish using `session.create_transaction()`. Below, we will perform a more complicated `SELECT` statement, make several changes to our collection of users and email addresess, and then create a new user with two email addresses, within the context of a transaction. We will perform a `flush()` in the middle of it to write the changes we have so far, and then allow the remaining changes to be written when we finally `commit()` the transaction. We enclose our operations within a `try/except` block to insure that resources are properly freed: +You may have noticed from the example above that when we say `session.flush()`, SQLAlchemy indicates the names `BEGIN` and `COMMIT` to indicate a transaction with the database. The `flush()` method, since it may execute many statements in a row, will automatically use a transaction in order to execute these instructions. But what if we want to use `flush()` inside of a larger transaction? This is performed via the `SessionTransaction` object, which we can establish using `session.create_transaction()`. Below, we will perform a more complicated `SELECT` statement, make several changes to our collection of users and email addresess, and then create a new user with two email addresses, within the context of a transaction. We will perform a `flush()` in the middle of it to write the changes we have so far, and then allow the remaining changes to be written when we finally `commit()` the transaction. We enclose our operations within a `try/except` block to ensure that resources are properly freed: {python} >>> transaction = session.create_transaction() diff --git a/doc/build/content/unitofwork.txt b/doc/build/content/unitofwork.txt index b417731580..a8d76ed7d0 100644 --- a/doc/build/content/unitofwork.txt +++ b/doc/build/content/unitofwork.txt @@ -67,7 +67,7 @@ We will now cover some of the key concepts used by Sessions and its underlying U ### Introduction to the Identity Map {@name=identitymap} -A primary concept of the Session's underlying Unit of Work is that it is keeps track of all persistent instances; recall that a persistent instance has a database identity and is attached to a Session. In particular, the Unit of Work must insure that only *one* copy of a particular persistent instance exists within the Session at any given time. The UOW accomplishes this task using a dictionary known as an *Identity Map*. +A primary concept of the Session's underlying Unit of Work is that it is keeps track of all persistent instances; recall that a persistent instance has a database identity and is attached to a Session. In particular, the Unit of Work must ensure that only *one* copy of a particular persistent instance exists within the Session at any given time. The UOW accomplishes this task using a dictionary known as an *Identity Map*. When a `Query` is used to issue `select` or `get` requests to the database, it will in nearly all cases result in an actual SQL execution to the database, and a corresponding traversal of rows received from that execution. However, when the underlying mapper actually *creates* objects corresponding to the result set rows it receives, it will check the session's identity map first before instantating a new object, and return the same instance already present in the identity map if it already exists, essentially *ignoring* the object state represented by that row. There are several ways to override this behavior and truly refresh an already-loaded instance which are described later, but the main idea is that once your instance is loaded into a particular Session, it will *never change* its state without your explicit approval, regardless of what the database says about it. @@ -223,7 +223,7 @@ The primary guideline for dealing with `flush()` is, the developer is responsibl #### close() {@name=close} -This method first calls `clear()`, removing all objects from this `Session`, and then insures that any transactional resources are closed. +This method first calls `clear()`, removing all objects from this `Session`, and then ensures that any transactional resources are closed. #### delete() {@name=delete} diff --git a/lib/sqlalchemy/ansisql.py b/lib/sqlalchemy/ansisql.py index e470a2101c..225188eb3f 100644 --- a/lib/sqlalchemy/ansisql.py +++ b/lib/sqlalchemy/ansisql.py @@ -321,7 +321,7 @@ class ANSICompiler(sql.Compiled): # redefine the generated name of the bind param in the case # that we have multiple conflicting bind parameters. while self.binds.setdefault(key, bindparam) is not bindparam: - # insure the name doesn't expand the length of the string + # ensure the name doesn't expand the length of the string # in case we're at the edge of max identifier length tag = "_%d" % count key = bindparam.key[0 : len(bindparam.key) - len(tag)] + tag diff --git a/lib/sqlalchemy/orm/dependency.py b/lib/sqlalchemy/orm/dependency.py index 4106d5c373..a49d216ae0 100644 --- a/lib/sqlalchemy/orm/dependency.py +++ b/lib/sqlalchemy/orm/dependency.py @@ -70,7 +70,7 @@ class DependencyProcessor(object): raise NotImplementedError() def preprocess_dependencies(self, task, deplist, uowcommit, delete = False): - """used before the flushes' topological sort to traverse through related objects and insure every + """used before the flushes' topological sort to traverse through related objects and ensure every instance which will require save/update/delete is properly added to the UOWTransaction.""" raise NotImplementedError() diff --git a/lib/sqlalchemy/orm/mapper.py b/lib/sqlalchemy/orm/mapper.py index 7de5135083..6c155f2074 100644 --- a/lib/sqlalchemy/orm/mapper.py +++ b/lib/sqlalchemy/orm/mapper.py @@ -94,7 +94,7 @@ class Mapper(object): information was loaded from the database. version_id_col - a Column which must have an integer type that will be used to keep a running "version id" of - mapped entities in the database. this is used during save operations to insure that no other thread or process + mapped entities in the database. this is used during save operations to ensure that no other thread or process has updated the instance during the lifetime of the entity, else a ConcurrentModificationError exception is thrown. polymorphic_on - used with mappers in an inheritance relationship, a Column which will identify the class/mapper diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 6c978f3620..425a7160dc 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -235,7 +235,7 @@ class Query(object): For more advanced usage, arg can also be a Select statement object, which will be executed and its resulting rowset used to build new object instances. - in this case, the developer must insure that an adequate set of columns exists in the + in this case, the developer must ensure that an adequate set of columns exists in the rowset with which to build new object instances.""" ret = self.extension.select(self, arg=arg, **kwargs) @@ -455,7 +455,7 @@ class Query(object): if order_by: statement.order_by(*util.to_list(order_by)) # for a DISTINCT query, you need the columns explicitly specified in order - # to use it in "order_by". insure they are in the column criterion (particularly oid). + # to use it in "order_by". ensure they are in the column criterion (particularly oid). # TODO: this should be done at the SQL level not the mapper level if kwargs.get('distinct', False) and order_by: [statement.append_column(c) for c in util.to_list(order_by)] diff --git a/lib/sqlalchemy/orm/unitofwork.py b/lib/sqlalchemy/orm/unitofwork.py index 3f2583eafc..34da55780e 100644 --- a/lib/sqlalchemy/orm/unitofwork.py +++ b/lib/sqlalchemy/orm/unitofwork.py @@ -305,7 +305,7 @@ class UOWTransaction(object): task.dependencies.add(up) def execute(self): - # insure that we have a UOWTask for every mapper that will be involved + # ensure that we have a UOWTask for every mapper that will be involved # in the topological sort [self.get_task_by_mapper(m) for m in self._get_noninheriting_mappers()] -- 2.47.2