| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
| |
- start writing docs
|
|
|
|
| |
sqlalchemy/orm, sqlalchemy/event, sqlalchemy/testing
|
|
|
|
| |
to get all flake8 passing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
implicitly initialized to None via first access; this action,
which has always resulted in a population of the attribute,
now emits an attribute event just like any other attribute set
operation and generates the same kind of history as one. Additionally,
many mapper internal operations will no longer implicitly generate
these "None" values when various never-set attributes are checked.
These are subtle behavioral fixes to attribute mechanics which provide
a better solution to the problem of :ticket:`3060`, which also
involves recognition of attributes explicitly set to ``None``
vs. attributes that were never set.
fixes #3061
|
|
|
|
|
|
|
|
|
|
|
| |
scenario, where an INSERT/DELETE can be turned into an UPDATE.
In this situation, a many-to-one relationship set to None, or
in some cases a scalar attribute set to None, may not be detected
as a net change in value, and therefore the UPDATE would not reset
what was on the previous row. This is due to some as-yet
unresovled side effects of the way attribute history works in terms
of implicitly assuming None isn't really a "change" for a previously
un-set attribute. See also :ticket:`3061`. fixes #3060
|
| |
|
|
|
|
|
|
|
| |
of cascading a natural primary key update will succeed
even if the key is composite and only some of the
attributes have changed.
[ticket:2665]
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
| |
- break out key mechanics of loading objects
into new "orm.loading" module, removing implementation
details from both mapper.py and query.py. is analogous
to persistence.py
- some other cleanup and old cruft removal
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
* 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)
|
|
|
|
|
|
|
| |
persistence.py - Mapper loses awareness of how to emit INSERT/UPDATE/DELETE,
persistence.py is only used by unitofwork.py. Then break each method out
into a top level with almost no logic, calling into _organize_states_for_XYZ(),
_collect_XYZ_commands(), _emit_XYZ_statements().
|
| |
|
|
|
|
|
|
|
|
| |
execute syncrule for destination column 'q';
mapper 'X' does not map this column" to
reference the correct mapper. [ticket:2163].
Also in 0.6.8.
- test/orm/test_sync.py covers orm/sync.py 100%
|
| |
|
|
|
|
|
|
| |
PASSIVE_OFF, now expresed as non-boolean symbols
- make "passive" available positionally on all get_history() methods,
call it like that
|
| |
|
|
|
|
|
| |
a consistent tag
- AUTHORS file
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
another, or vice versa changing the referenced
object by an m2o, where the foreign key is also a
member of the primary key, will now be more
carefully checked during flush if the change in
value of the foreign key on the "many" side is the
result of a change in the primary key of the "one"
side, or if the "one" is just a different object.
In one case, a cascade-capable DB would have
cascaded the value already and we need to look at
the "new" PK value to do an UPDATE, in the other we
need to continue looking at the "old". We now look
at the "old", assuming passive_updates=True,
unless we know it was a PK switch that
triggered the change. [ticket:1856]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- one-to-many relationships now maintain a list of positive
parent-child associations within the flush, preventing
previous parents marked as deleted from cascading a
delete or NULL foreign key set on those child objects,
despite the end-user not removing the child from the old
association. [ticket:1764]
- re-established Preprocess as unique on their arguments,
as they were definitely duped in inheritance scenarios
- added a "memo" feature to UOWTransaction which represents the usual
pattern of using the .attributes collection
- added the test case from [ticket:1081] into perf/
|
|
|
|
|
|
|
|
|
| |
_set_state_attr_by_column, others,
to reduce on expensive state.dict calls.
- internal getattr(), setattr(), getcommitted() methods
on ColumnProperty, CompositeProperty, RelationshipProperty
have been underscored, signature has changed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
object, and ON UPDATE CASCADE will be taken into account when
the flush happens. Set the new "passive_updates" flag to False
on mapper() when using SQLite or MySQL/MyISAM. [ticket:1362]
- flush() now detects when a primary key column was updated by
an ON UPDATE CASCADE operation from another primary key, and
can then locate the row for a subsequent UPDATE on the new PK
value. This occurs when a relation() is there to establish
the relationship as well as passive_updates=True. [ticket:1671]
|
| |
|
|
|
|
|
|
|
|
|
|
|
| |
i.e. operations that were scanning the full session,
including an extremely expensive one that was erroneously
assuming primary key values were changing when this
was not the case.
* one edge case remains which may invoke a full scan,
if an existing primary key attribute is modified
to a new value.
|
| |
|
|
|
|
|
| |
- Repaired support for "passive-deletes" on a many-to-one
relation() with "delete" cascade. [ticket:1183]
|
|
|
|
| |
0.4 development continues at /sqlalchemy/branches/rel_0_4
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- The methodology behind "primaryjoin"/"secondaryjoin" has
been refactored. Behavior should be slightly more
intelligent, primarily in terms of error messages which
have been pared down to be more readable. In a slight
number of scenarios it can better resolve the correct
foreign key than before.
- moved collections unit test from relationships.py to collection.py
- PropertyLoader now has "synchronize_pairs" and "equated_pairs"
collections which allow easy access to the source/destination
parent/child relation between columns (might change names)
- factored out ClauseSynchronizer (finally)
- added many more tests for priamryjoin/secondaryjoin
error checks
|
| |
|
|
|
|
|
|
|
|
| |
(such as PickleTypes)
- added a more descriptive error message when flushing on a
relation() that has non-locally-mapped columns in its primary or
secondary join condition
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
changed freely, and the identity of the instance will change upon
flush. In addition, update cascades of foreign key referents (primary
key or not) along relations are supported, either in tandem with the
database's ON UPDATE CASCADE (required for DB's like Postgres) or
issued directly by the ORM in the form of UPDATE statements, by setting
the flag "passive_cascades=False".
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
- topological.py cleaned up, presents three public facing functions which
return list/tuple based structures, without exposing any internals. only
the third function returns the "hierarchical" structure. when results
include "cycles" or "child" items, 2- or 3- tuples are used to represent
results.
- unitofwork uses InstanceState almost exclusively now. new and deleted lists
are now dicts which ref the actual object to provide a strong ref for the
duration that they're in those lists. IdentitySet is only used for the public
facing versions of "new" and "deleted".
- unitofwork topological sort no longer uses the "hierarchical" version of the sort
for the base sort, only for the "per-object" secondary sort where it still
helps to group non-dependent operations together and provides expected insert
order. the default sort deals with UOWTasks in a straight list and is greatly
simplified. Tests all pass but need to see if svilen's stuff still works,
one block of code in _sort_cyclical_dependencies() seems to not be needed anywhere
but i definitely put it there for a reason at some point; if not hopefully we
can derive more test coverage from that.
- the UOWEventHandler is only applied to object-storing attributes, not
scalar (i.e. column-based) ones. cuts out a ton of overhead when setting
non-object based attributes.
- InstanceState also used throughout the flush process, i.e. dependency.py,
mapper.save_obj()/delete_obj(), sync.execute() all expect InstanceState objects
in most cases now.
- mapper/property cascade_iterator() takes InstanceState as its argument,
but still returns lists of object instances so that they are not dereferenced.
- a few tricks needed when dealing with InstanceState, i.e. when loading a list
of items that are possibly fresh from the DB, you *have* to get the actual objects
into a strong-referencing datastructure else they fall out of scope immediately.
dependency.py caches lists of dependent objects which it loads now (i.e. history
collections).
- AttributeHistory is gone, replaced by a function that returns a 3-tuple of
added, unchanged, deleted. these collections still reference the object
instances directly for the strong-referencing reasons mentiontioned, but
it uses less IdentitySet logic to generate.
|
|
|
|
|
|
|
|
| |
mapper.get_attr_by_column(), mapper.set_attr_by_column(),
mapper.pks_by_table, mapper.cascade_callable(),
MapperProperty.cascade_callable(), mapper.canload()
- refinements to mapper PK/table column organization, session cascading,
some naming convention work
|
| |
|
|
|
|
|
|
|
| |
target mapper. this was revealed by
recent attributes.py change in r3695 that causes a value of "None" to register as part of the attribute history's
added_items() collection (i.e. since AttributeHistory compares against NO_VALUE instead of None).
|
|
|
|
| |
conditions [ticket:769]
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
2. compiler names changed to be less verbose, unused classes removed.
3. Methods on Dialect which return compilers, schema generators, identifier preparers
have changed to direct class references, typically on the Dialect class itself
or optionally as attributes on an individual Dialect instance if conditional behavior is needed.
This takes away the need for Dialect subclasses to know how to instantiate these
objects, and also reduces method overhead by one call for each one.
4. as a result of 3., some internal signatures have changed for things like compiler() (now statement_compiler()), preparer(), etc., mostly in that the dialect needs to be passed explicitly as the first argument (since they are just class references now). The compiler() method on Engine and Connection is now also named statement_compiler(), but as before does not take the dialect as an argument.
5. changed _process_row function on RowProxy to be a class reference, cuts out 50K method calls from insertspeed.py
|
|
|
|
| |
maintenance branch in branches/rel_0_3.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
SchemaItem so that the traversal of items is controlled by the
ClauseVisitor itself, using the method visitor.traverse(item).
accept_visitor() methods can still be called directly but will
not do any traversal of child items. ClauseElement/SchemaItem now
have a configurable get_children() method to return the collection
of child elements for each parent object. This allows the full
traversal of items to be clear and unambiguous (as well as loggable),
with an easy method of limiting a traversal (just pass flags which
are picked up by appropriate get_children() methods). [ticket:501]
- accept_schema_visitor() methods removed, replaced with
get_children(schema_visitor=True)
- various docstring/changelog cleanup/reformatting
|
|
|
|
|
|
| |
straight <pre> + trim() func
for now. applies most of [ticket:214], compliemnts of Lele Gaifax
|
|
|
|
|
|
|
| |
as PK/FK
on the child would raise a "blank out the primary key" error, if manually deleted
or "delete" cascade without "delete-orphan" was used
|