summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/persistence.py
Commit message (Collapse)AuthorAgeFilesLines
* Warn instead of raise for unmapped column that matches on keyticket_4073Mike Bayer2017-09-101-4/+4
| | | | | | | | | | | | | | | Modified the change made to the ORM update/delete evaluator in :ticket:`3366` such that if an unmapped column expression is present in the update or delete, if the evaluator can match its name to the mapped columns of the target class, a warning is emitted, rather than raising UnevaluatableError. This is essentially the pre-1.2 behavior, and is to allow migration for applications that are currently relying upon this pattern. However, if the given attribute name cannot be matched to the columns of the mapper, the UnevaluatableError is still raised, which is what was fixed in :ticket:`3366`. Change-Id: I658ed0dbf485b7f8009774f9c12d9912447abd2a Fixes: #4073
* Additional fixes to sane rowcountMike Bayer2017-08-311-2/+12
| | | | | | | | Implement rowcount assertions and single row check for post_update as well as deletes. Change-Id: I4e5ba7e8747bf0e0b41f569089eb8cdbf064b7a9 Fixes: #4062
* Add new sane_rowcount_w_returning flagMike Bayer2017-08-311-9/+15
| | | | | | | | | | | | | | | | | Added a new class of "rowcount support" for dialects that is specific to when "RETURNING", which on SQL Server looks like "OUTPUT inserted", is in use, as the PyODBC backend isn't able to give us rowcount on an UPDATE or DELETE statement when OUTPUT is in effect. This primarily affects the ORM when a flush is updating a row that contains server-calcluated values, raising an error if the backend does not return the expected row count. PyODBC now states that it supports rowcount except if OUTPUT.inserted is present, which is taken into account by the ORM during a flush as to whether it will look for a rowcount. ORM tests are implicit in existing tests run against PyODBC Fixes: #4062 Change-Id: Iff17cbe4c7a5742971ed85a4d58660c18cc569c2
* Check for column object in eval_none, not propkeyMike Bayer2017-07-181-1/+1
| | | | | | | | | | Fixed bug involving JSON NULL evaluation logic added in 1.1 as part of :ticket:`3514` where the logic would not accommodate ORM mapped attributes named differently from the :class:`.Column` that was mapped. Change-Id: I1848afcfb63ad7f074f315d8d3097666069b42be Fixes: #4031
* Add all versioning logic to _post_update()Mike Bayer2017-06-151-17/+93
| | | | | | | | | | An UPDATE emitted as a result of the :paramref:`.relationship.post_update` feature will now integrate with the versioning feature to both bump the version id of the row as well as assert that the existing version number was matched. Fixes: #3496 Change-Id: I865405dd6069f1c1e3b0d27a4980e9374e059f97
* Re-send column value w/ onupdate default during post-updateMike Bayer2017-06-061-1/+1
| | | | | | | | | | | Adjusted the behavior of post_update such that if a column with an "onupdate" default has received an explicit value for INSERT, re-send the same data during a post-update UPDATE so that the value remains in effect, rather than an onupdate overwriting it. Change-Id: I26bccb6f957dcad07a2bcbda2dd9e14c60b92b06 Fixes: #3471
* Implement _postfetch_post_update to expire/refresh onupdates in post_updateMike Bayer2017-06-051-5/+39
| | | | | | | | | | | | Fixed bug involving the :paramref:`.relationship.post_update` feature where a column "onupdate" value would not result in expiration or refresh of the corresponding object attribute, if the UPDATE for the row were a result of the "post update" feature. Additionally, the :meth:`.SessionEvents.refresh_flush` event is now emitted for these attributes when refreshed within the flush. Fixes: #3472 Change-Id: I5ee2d715e773a306ab1e8143e4382c228991ac78
* detect and raise for version_id is NULLDiana Clarke2017-05-221-0/+5
| | | | | | | | | The versioning feature does not support NULL for the version counter. An exception is now raised if the version id is programmatic and was set to NULL for an UPDATE. Pull request courtesy Diana Clarke. Fixes: #3673 Change-Id: I8b0da56234a7c7f5e7fde35536e09a6216a5e48a
* Detect no params w/ manual version_id counter and set to itselfMike Bayer2017-05-221-0/+7
| | | | | | | | | | | | | | Fixed bug where programmatic version_id counter in conjunction with joined table inheritance would fail if the version_id counter were not actually incremented and no other values on the base table were modified, as the UPDATE would have an empty SET clause. Since programmatic version_id where version counter is not incremented is a documented use case, this specific condition is now detected and the UPDATE now sets the version_id value to itself, so that concurrency checks still take place. Change-Id: I80e385bffeed4851cc20131cbe983c173a46f655 Fixes: #3996
* Add conditionals specific to deferred for expire ro propertiesMike Bayer2017-05-101-2/+10
| | | | | | | | | | Fixed bug where a :func:`.column_property` that is also marked as "deferred" would be marked as "expired" during a flush, causing it to be loaded along with the unexpiry of regular attributes even though this attribute was never accessed. Change-Id: Iaa9e17b66ece30a8e729e4af746b31ff99b1ec9a Fixes: #3984
* Support hybrids/composites with bulk updatesMike Bayer2017-03-221-49/+60
| | | | | | | | | | | The :meth:`.Query.update` method can now accommodate both hybrid attributes as well as composite attributes as a source of the key to be placed in the SET clause. For hybrids, an additional decorator :meth:`.hybrid_property.update_expression` is supplied for which the user supplies a tuple-returning function. Change-Id: I15e97b02381d553f30b3301308155e19128d2cfb Fixes: #3229
* New features from python 2.7Катаев Денис2017-03-171-1/+1
| | | | | | | After bump minimum supported version to 2.7 (1da9d3752160430c91534a8868ceb8c5ad1451d4), we can use new syntax. Change-Id: Ib064c75a00562e641d132f9c57e5e69744200e05 Pull-request: https://github.com/zzzeek/sqlalchemy/pull/347
* Check for columns not part of mapping, correct mapping for eager_defaultsMike Bayer2017-02-091-4/+11
| | | | | | | | | | | | | Fixed two closely related bugs involving the mapper eager_defaults flag in conjunction with single-table inheritance; one where the eager defaults logic would inadvertently try to access a column that's part of the mapper's "exclude_properties" list (used by Declarative with single table inheritance) during the eager defaults fetch, and the other where the full load of the row in order to fetch the defaults would fail to use the correct inheriting mapper. Fixes: #3908 Change-Id: Ie745174c917d512e2c46d9e3cc14512cde53cc9a
* Don't post-SELECT columns w/o a server default/onupdate for eager_defaultsMike Bayer2017-02-081-2/+6
| | | | | | | | | | | | | | Fixed a major inefficiency in the "eager_defaults" feature whereby an unnecessary SELECT would be emitted for column values where the ORM had explicitly inserted NULL, corresponding to attributes that were unset on the object but did not have any server default specified, as well as expired attributes on update that nevertheless had no server onupdate set up. As these columns are not part of the RETURNING that eager_defaults tries to use, they should not be post-SELECTed either. Change-Id: I0d4f1e9d3d9717d68dcc0592f69456a1f1c36df8 Fixes: #3909
* update for 2017 copyrightMike Bayer2017-01-041-1/+1
| | | | Change-Id: I4e8c2aa8fe817bb2af8707410fa0201f938781de
* Consider version_id_prop when emitting bulk UPDATEMike Bayer2016-11-101-1/+6
| | | | | | | | | The version id needs to be part of _changed_dict() so that the value is present to send to _emit_update_statements() Change-Id: Ia85f0ef7714296a75cdc6c88674805afbbe752c8 Fixes: #3781
* Ensure attribute keys used for bulk update pk setMike Bayer2016-11-101-1/+1
| | | | | | | | Fixed bug in :meth:`.Session.bulk_update_mappings` where an alternate-named primary key attribute would not track properly into the UPDATE statement. Change-Id: I33e9140f45827772768fa548adcfeb4dbfc2208d Fixes: #3849
* Rewrite migration notes for [ticket:3514]Mike Bayer2016-10-191-0/+6
| | | | | | | | | | | | | | | | | | | The change to "evaluates none" datatypes in the ORM was not fully described in the migration notes, missing the key behavioral change that a column which is missing a default entirely will not receive a value for a missing JSON column now. The issue here touched upon a revisit of the assumptions in [ticket:3514], but overall the old behavior "worked" mostly because the ORM wants to explicitly render NULL into an INSERT for column values that are missing, which itself is a legacy behavior which should be considered for possible removal in a future major release. Given that "missing ORM value + no column default set up == dont put it in the INSERT" would be the most intuitive behavior, the move in [ticket:3514] represents a step in this direction. Change-Id: I454d5bb0773bd73d9864925dcc47f1f0810e33ba Fixes: #3830
* Check for __clause_element__() in ORM insert/updateMike Bayer2016-10-051-4/+8
| | | | | | | | | | | | | | | | ORM attributes can now be assigned any object that is has a ``__clause_element__()`` attribute, which will result in inline SQL the way any :class:`.ClauseElement` class does. This covers other mapped attributes not otherwise transformed by further expression constructs. As part of this, it was considered that we could add __clause_element__() to ClauseElement, however this causes endless loops in a "while" pattern and this pattern has been identified in third party libraries. Add a test to ensure we never make that change. Change-Id: I9e15b3f1c4883fd3909acbf7dc81d034c6e3ce1d Fixes: #3802
* Allow SQL expressions to be set on PK columnsMike Bayer2016-09-201-9/+19
| | | | | | | | | | | | | Removes an unnecessary transfer of modified PK column value to the params dictionary, so that if the modified PK column is already present in value_params, this remains in effect. Also propagate a new flag through to _emit_update_statements() that will trip "return_defaults()" across the board if a PK col w/ SQL expression change is present, and pull this PK value in _postfetch as well assuming we're an UPDATE. Change-Id: I9ae87f964df9ba8faea8e25e96b8327f968e5d1b Fixes: #3801
* Add "render_nulls" flag to bulk_insert as optional performance optimizationtsauerwein2016-06-061-4/+6
| | | | | | | | | | | | | | Currently, ``Session.bulk_insert_mappings`` omits NULL values which causes it to break up batches of inserts based on which batches contain NULL and which do not. By adding this flag, the same columns are rendered in the INSERT for all rows allowing them to be batched. The downside is that server-side defaults are omitted. Doctext-author: Mike Bayer <mike_mp@zzzcomputing.com> Change-Id: Iec5969304d4bdbf57290b200331bde02254aa3a5 Pull-request: https://github.com/zzzeek/sqlalchemy/pull/243
* - Fixed bug where a newly inserted instance that is rolled backMike Bayer2016-03-141-16/+18
| | | | | | | | | would still potentially cause persistence conflicts on the next transaction, because the instance would not be checked that it was expired. This fix will resolve a large class of cases that erronously cause the "New instance with identity X conflicts with persistent instance Y" error. fixes #3677
* - happy new yearMike Bayer2016-01-291-1/+1
|
* - Added new parameter :paramref:`.orm.mapper.passive_deletes` toMike Bayer2016-01-201-0/+2
| | | | | | | | available mapper options. This allows a DELETE to proceed for a joined-table inheritance mapping against the base table only, while allowing for ON DELETE CASCADE to handle deleting the row from the subclass tables. fixes #2349
* - since we are mutating the statement in a loop, start withMike Bayer2015-12-141-3/+8
| | | | | | the same cached starting statement each time. no issue has been observed with the former but it could perhaps have issues w/ versioning or eager_defaults
* - Fixed bug where :meth:`.Session.bulk_update_mappings` and relatedMike Bayer2015-12-141-1/+1
| | | | | | | | would not bump a version id counter when in use. The experience here is still a little rough as the original version id is required in the given dictionaries and there's not clean error reporting on that yet. fixes #3610
* - Fixed bug in :meth:`.Update.return_defaults` which would cause allMike Bayer2015-12-141-13/+23
| | | | | | | | | | | | | | insert-default holding columns not otherwise included in the SET clause (such as primary key cols) to get rendered into the RETURNING even though this is an UPDATE. - Major fixes to the :paramref:`.Mapper.eager_defaults` flag, this flag would not be honored correctly in the case that multiple UPDATE statements were to be emitted, either as part of a flush or a bulk update operation. Additionally, RETURNING would be emitted unnecessarily within update statements. fixes #3609
* - Added support for parameter-ordered SET clauses in an UPDATEMike Bayer2015-11-281-4/+12
| | | | | | | | | | statement. This feature is available by passing the :paramref:`~.sqlalchemy.sql.expression.update.preserve_parameter_order` flag either to the core :class:`.Update` construct or alternatively adding it to the :paramref:`.Query.update.update_args` dictionary at the ORM-level, also passing the parameters themselves as a list of 2-tuples. Thanks to Gorka Eguileor for implementation and tests. adapted from pullreq github:200
* - adjust 4f54607923a11669961b53f where we still allow_multirow as longMike Bayer2015-10-191-1/+1
| | | | as versioning isn't needed, fixes test_unitofworkv2->test_update_multi_missing_broken_multi_rowcount
* - Fixed regression in 1.0 where new feature of using "executemany"Mike Bayer2015-10-191-1/+1
| | | | | | | | | for UPDATE statements in the ORM (e.g. :ref:`feature_updatemany`) would break on Postgresql and other RETURNING backends when using server-side version generation schemes, as the server side value is retrieved via RETURNING which is not supported with executemany. fixes #3556
* - Internal calls to "bookkeeping" functions withinMike Bayer2015-09-081-48/+56
| | | | | | | | :meth:`.Session.bulk_save_objects` and related bulk methods have been scaled back to the extent that this functionality is not currently used, e.g. checks for column default values to be fetched after an INSERT or UPDATE statement. fixes #3526
* - Fixed bug in :meth:`.Session.bulk_save_objects` where a mappedMike Bayer2015-09-081-1/+7
| | | | | | | column that had some kind of "fetch on update" value and was not locally present in the given object would cause an AttributeError within the operation. fixes #3525
* - merge of ticket_3514 None-handling branchMike Bayer2015-08-171-1/+3
| | | | | | | | | | | | | | | | - Fixes to the ORM and to the postgresql JSON type regarding the ``None`` constant in conjunction with the Postgresql :class:`.JSON` type. When the :paramref:`.JSON.none_as_null` flag is left at its default value of ``False``, the ORM will now correctly insert the Json "'null'" string into the column whenever the value on the ORM object is set to the value ``None`` or when the value ``None`` is used with :meth:`.Session.bulk_insert_mappings`, **including** if the column has a default or server default on it. This makes use of a new type-level flag "evaluates_none" which is implemented by the JSON type based on the none_as_null flag. fixes #3514 - Added a new constant :attr:`.postgresql.JSON.NULL`, indicating that the JSON NULL value should be used for a value regardless of other settings. part of fixes #3514
* - Fixed 1.0 regression where value objects that overrideMike Bayer2015-07-011-2/+4
| | | | | | | | | ``__eq__()`` to return a non-boolean-capable object, such as some geoalchemy types as well as numpy types, were being tested for ``bool()`` during a unit of work update operation, where in 0.9 the return value of ``__eq__()`` was tested against "is True" to guard against this. fixes #3469
* - Fixed a major regression in the 1.0 series where the version_id_counterMike Bayer2015-06-241-1/+18
| | | | | | | | | | | | | feature would cause an object's version counter to be incremented when there was no net change to the object's row, but instead an object related to it via relationship (e.g. typically many-to-one) were associated or de-associated with it, resulting in an UPDATE statement that updates the object's version counter and nothing else. In the use case where the relatively recent "server side" and/or "programmatic/conditional" version counter feature were used (e.g. setting version_id_generator to False), the bug could cause an UPDATE without a valid SET clause to be emitted. fixes #3465
* - restore the approach we have for pk_params, but in orderMike Bayer2015-06-131-6/+8
| | | | | to suit #3451 exclude these columns from the "params" dictionary in the first place, revises pr github:181
* Fix primary key behaviour in bulk_updatepr/181Patrick Hayes2015-06-131-6/+5
| | | | | | | | | | | | | | | | | | | | | | | Suppose you have a model class with a primary key. Base = declarative_base() class User(Base): id = Column(BigInteger, primary_key=True) name = Column(String) Previously, running `bulk_update_mappings(User, {'id': 1, 'name': 'hello'})` would emit the following: ```UPDATE users SET id=1, name='hello' WHERE id=1``` This is contrary to the stated behaviour, where primary keys are omitted from the SET clause. Furthermore, this behaviour is harmful, as it can cause the db engine to lock over-aggresively (at least in Postgres). With this change, the emitted SQL is: ```UPDATE users SET name='hello' WHERE id=1```
* - Fixed regression in the :mod:`sqlalchemy.ext.mutable` extensionMike Bayer2015-05-211-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | as a result of the bugfix for :ticket:`3167`, where attribute and validation events are no longer called within the flush process. The mutable extension was relying upon this behavior in the case where a column level Python-side default were responsible for generating the new value on INSERT or UPDATE, or when a value were fetched from the RETURNING clause for "eager defaults" mode. The new value would not be subject to any event when populated and the mutable extension could not establish proper coercion or history listening. A new event :meth:`.InstanceEvents.refresh_flush` is added which the mutable extension now makes use of for this use case. fixes #3427 - Added new event :meth:`.InstanceEvents.refresh_flush`, invoked when an INSERT or UPDATE level default value fetched via RETURNING or Python-side default is invoked within the flush process. This is to provide a hook that is no longer present as a result of :ticket:`3167`, where attribute and validation events are no longer called within the flush process. - Added a new semi-public method to :class:`.MutableBase` :meth:`.MutableBase._get_listen_keys`. Overriding this method is needed in the case where a :class:`.MutableBase` subclass needs events to propagate for attribute keys other than the key to which the mutable type is associated with, when intercepting the :meth:`.InstanceEvents.refresh` or :meth:`.InstanceEvents.refresh_flush` events. The current example of this is composites using :class:`.MutableComposite`.
* - Fixed regression from 0.9.10 prior to release due to :ticket:`3349`Mike Bayer2015-04-301-8/+8
| | | | | | | | where the check for query state on :meth:`.Query.update` or :meth:`.Query.delete` compared the empty tuple to itself using ``is``, which fails on Pypy to produce ``True`` in this case; this would erronously emit a warning in 0.9 and raise an exception in 1.0. fixes #3405
* - Fixed regression within the flush process when an attribute wereMike Bayer2015-04-291-5/+4
| | | | | | | | | set to a SQL expression for an UPDATE, and the SQL expression when compared to the previous value of the attribute would produce a SQL comparison other than ``==`` or ``!=``, the exception "Boolean value of this clause is not defined" would raise. The fix ensures that the unit of work will not interpret the SQL expression in this way. fixes #3402
* - Fixed more regressions caused by NEVER_SET; comparisonsMike Bayer2015-04-201-1/+1
| | | | | | | | | to transient objects with attributes unset would leak NEVER_SET, and negated_contains_or_equals would do so for any transient object as the comparison used only the committed value. Repaired the NEVER_SET cases, fixes #3371, and also made negated_contains_or_equals() use state_attr_by_column() just like a non-negated comparison, fixes #3374
* Merge remote-tracking branch 'origin/pr/164' into pr164Mike Bayer2015-04-031-4/+6
|\
| * Allow kwargs to be passed through update()pr/164Amir Sadoughi2015-03-201-4/+6
| | | | | | | | | | This is useful to be able to pass in mysql_limit=1 from using the ORM.
* | - :class:`.Query` doesn't support joins, subselects, or specialMike Bayer2015-04-011-10/+46
|/ | | | | | | | | | | | | | | FROM clauses when using the :meth:`.Query.update` or :meth:`.Query.delete` methods; instead of silently ignoring these fields if methods like :meth:`.Query.join` or :meth:`.Query.select_from` has been called, an error is raised. In 0.9.10 this only emits a warning. fixes #3349 - don't needlessly call _compile_context() and build up a whole statement that we never need. Construct QueryContext as it's part of the event contract, but don't actually call upon mapper attributes; use more direct systems of determining the update or delete table. - don't realy need _no_select_modifiers anymore
* - copyright 2015Mike Bayer2015-03-101-1/+1
|
* - restore r611883ffb35ca6664649f6328ae8 with additional fixes and an ↵Mike Bayer2015-01-191-4/+8
| | | | | | additional test that is much more specific to #1326
* - reverse the last commit temporarily as it breaks all the polymorphic casesMike Bayer2015-01-191-8/+4
|
* - The primary :class:`.Mapper` of a :class:`.Query` is now passed to theMike Bayer2015-01-191-4/+8
| | | | | | | | | | | :meth:`.Session.get_bind` method when calling upon :meth:`.Query.count`, :meth:`.Query.update`, :meth:`.Query.delete`, as well as queries against mapped columns, :obj:`.column_property` objects, and SQL functions and expressions derived from mapped columns. This allows sessions that rely upon either customized :meth:`.Session.get_bind` schemes or "bound" metadata to work in all relevant cases. fixes #3227 fixes #3242 fixes #1326
* - further fixes and even better tests for this blockMike Bayer2015-01-191-3/+8
|
* - another adjustmentMike Bayer2015-01-191-2/+3
|