summaryrefslogtreecommitdiff
path: root/test/orm/dml
Commit message (Collapse)AuthorAgeFilesLines
* fix test on old sqliteFederico Caselli2023-05-051-0/+1
| | | | Change-Id: Ic7dbb7df6a10077eb28a721e151b2194ab3b1634
* add explicit step to set populate_existing for bulk insertMike Bayer2023-05-051-0/+71
| | | | | | | | | | Fixed issue in new :ref:`orm_queryguide_upsert_returning` feature where the ``populate_existing`` execution option was not being propagated to the loading option, preventing existing attributes from being refreshed in-place. Fixes: #9746 Change-Id: I3efcab644e2b5874c6b265d5313f353c051db629
* support parameters in all ORM insert modesMike Bayer2023-04-262-16/+319
| | | | | | | | | | | | | | | | | | | | Fixed 2.0 regression where use of :func:`_sql.bindparam()` inside of :meth:`_dml.Insert.values` would fail to be interpreted correctly when executing the :class:`_dml.Insert` statement using the ORM :class:`_orm.Session`, due to the new ORM-enabled insert feature not implementing this use case. In addition, the bulk INSERT and UPDATE features now add these capabilities: * The requirement that extra parameters aren't passed when using ORM INSERT using the "orm" dml_strategy setting is lifted. * The requirement that additional WHERE criteria is not passed when using ORM UPDATE using the "bulk" dml_strategy setting is lifted. Note that in this case, the check for expected row count is turned off. Fixes: #9583 Change-Id: I539c18893b697caeab5a5f0195a27d4f0487e728
* add deterministic imv returning ordering using sentinel columnsMike Bayer2023-04-211-139/+381
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Repaired a major shortcoming which was identified in the :ref:`engine_insertmanyvalues` performance optimization feature first introduced in the 2.0 series. This was a continuation of the change in 2.0.9 which disabled the SQL Server version of the feature due to a reliance in the ORM on apparent row ordering that is not guaranteed to take place. The fix applies new logic to all "insertmanyvalues" operations, which takes effect when a new parameter :paramref:`_dml.Insert.returning.sort_by_parameter_order` on the :meth:`_dml.Insert.returning` or :meth:`_dml.UpdateBase.return_defaults` methods, that through a combination of alternate SQL forms, direct correspondence of client side parameters, and in some cases downgrading to running row-at-a-time, will apply sorting to each batch of returned rows using correspondence to primary key or other unique values in each row which can be correlated to the input data. Performance impact is expected to be minimal as nearly all common primary key scenarios are suitable for parameter-ordered batching to be achieved for all backends other than SQLite, while "row-at-a-time" mode operates with a bare minimum of Python overhead compared to the very heavyweight approaches used in the 1.x series. For SQLite, there is no difference in performance when "row-at-a-time" mode is used. It's anticipated that with an efficient "row-at-a-time" INSERT with RETURNING batching capability, the "insertmanyvalues" feature can be later be more easily generalized to third party backends that include RETURNING support but not necessarily easy ways to guarantee a correspondence with parameter order. Fixes: #9618 References: #9603 Change-Id: I1d79353f5f19638f752936ba1c35e4dc235a8b7c
* try to omit unnecessary cols for ORM bulk insert + returningMike Bayer2023-04-211-21/+59
| | | | | | | | | Fixed bug in ORM bulk insert feature where additional unnecessary columns would be rendered in the INSERT statement if RETURNING of individual columns were requested. Fixes: #9685 Change-Id: Ibf5f06ab017215c7c9bd8850c3a006f73fe78c68
* rename EvaluatorCompiler to _EvaluatorCompilerMike Bayer2023-02-161-3/+3
| | | | | | | | This is a private class, mark as such as some users may have used this class directly in end-user code. Change-Id: I2657eff1f9f11b59c0483922ac67d6420a082906 References: #9299
* add requirement, restore test removed in ↵Federico Caselli2023-02-101-0/+1
| | | | | | eb0861e8e69f8ce702301c558e552e1aeb2e9eba Change-Id: I78c12a58eef59ff577a88880a8752151051fd939
* generalize adapt_on_names to expect non-named elementsMike Bayer2023-02-101-1/+36
| | | | | | | | | | | | | | | | | | | | The fix in #9217 opened up adapt_on_names to more kinds of expressions than it was prepared for; adjust that logic and also refine in the ORM where we are using it, as we dont need it (yet) for the DML RETURNING use case. Fixed regression introduced in version 2.0.2 due to :ticket:`9217` where using DML RETURNING statements, as well as :meth:`_sql.Select.from_statement` constructs as was "fixed" in :ticket:`9217`, in conjunction with ORM mapped classes that used expressions such as with :func:`_orm.column_property`, would lead to an internal error within Core where it would attempt to match the expression by name. The fix repairs the Core issue, and also adjusts the fix in :ticket:`9217` to not take effect for the DML RETURNING use case, where it adds unnecessary overhead. Fixes: #9273 Change-Id: Ie0344efb12ff7df48f21e71e62dc598c76a6a0de
* ensure whereclause, returning copied as tuplesMike Bayer2022-12-281-9/+25
| | | | | | | | | | Fixed issue in the internal SQL traversal for DML statements like :class:`_dml.Update` and :class:`_dml.Delete` which would cause among other potential issues, a specific issue using lambda statements with the ORM update/delete feature. Fixes: #9033 Change-Id: I76428049cb767ba302fbea89555114bf63ab8687
* Rewrite positional handling, test for "numeric"Federico Caselli2022-12-051-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Changed how the positional compilation is performed. It's rendered by the compiler the same as the pyformat compilation. The string is then processed to replace the placeholders with the correct ones, and to obtain the correct order of the parameters. This vastly simplifies the computation of the order of the parameters, that in case of nested CTE is very hard to compute correctly. Reworked how numeric paramstyle behavers: - added support for repeated parameter, without duplicating them like in normal positional dialects - implement insertmany support. This requires that the dialect supports out of order placehoders, since all parameters that are not part of the VALUES clauses are placed at the beginning of the parameter tuple - support for different identifiers for a numeric parameter. It's for example possible to use postgresql style placeholder $1, $2, etc Added two new dialect based on sqlite to test "numeric" fully using both :1 style and $1 style. Includes a workaround for SQLite's not-really-correct numeric implementation. Changed parmstyle of asyncpg dialect to use numeric, rendering with its native $ identifiers Fixes: #8926 Fixes: #8849 Change-Id: I7c640467d49adfe6d795cc84296fc7403dcad4d6
* Try running pyupgrade on the codeFederico Caselli2022-11-161-35/+29
| | | | | | | | command run is "pyupgrade --py37-plus --keep-runtime-typing --keep-percent-format <files...>" pyupgrade will change assert_ to assertTrue. That was reverted since assertTrue does not exists in sqlalchemy fixtures Change-Id: Ie1ed2675c7b11d893d78e028aad0d1576baebb55
* adjust update/delete test for non-orderingMike Bayer2022-11-081-5/+7
| | | | | | | this test sometimes has different ordering when running under CI Change-Id: I6dc3e24c6e23dc00a0ee5ba53e489ad813f12c58
* reconcile Mapper properties ordering against mapped TableMike Bayer2022-10-251-10/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Changed a fundamental configuration behavior of :class:`.Mapper`, where :class:`_schema.Column` objects that are explicitly present in the :paramref:`_orm.Mapper.properties` dictionary, either directly or enclosed within a mapper property object, will now be mapped within the order of how they appear within the mapped :class:`.Table` (or other selectable) itself (assuming they are in fact part of that table's list of columns), thereby maintaining the same order of columns in the mapped selectable as is instrumented on the mapped class, as well as what renders in an ORM SELECT statement for that mapper. Previously (where "previously" means since version 0.0.1), :class:`.Column` objects in the :paramref:`_orm.Mapper.properties` dictionary would always be mapped first, ahead of when the other columns in the mapped :class:`.Table` would be mapped, causing a discrepancy in the order in which the mapper would assign attributes to the mapped class as well as the order in which they would render in statements. The change most prominently takes place in the way that Declarative assigns declared columns to the :class:`.Mapper`, specifically how :class:`.Column` (or :func:`_orm.mapped_column`) objects are handled when they have a DDL name that is explicitly different from the mapped attribute name, as well as when constructs such as :func:`_orm.deferred` etc. are used. The new behavior will see the column ordering within the mapped :class:`.Table` being the same order in which the attributes are mapped onto the class, assigned within the :class:`.Mapper` itself, and rendered in ORM statements such as SELECT statements, independent of how the :class:`_schema.Column` was configured against the :class:`.Mapper`. Fixes: #8705 Change-Id: I95cc05061a97fe6b1654bab70e2f6da30f8f3bd3
* simplify unmapped col eval fallbackMike Bayer2022-10-172-9/+46
| | | | | | | | | | | | | Removed the warning that emits when using ORM-enabled update/delete regarding evaluation of columns by name, first added in :ticket:`4073`; this warning actually covers up a scenario that otherwise could populate the wrong Python value for an ORM mapped attribute depending on what the actual column is, so this deprecated case is removed. In 2.0, ORM enabled update/delete uses "auto" for "synchronize_session", which should do the right thing automatically for any given UPDATE expression. Fixes: #8656 Change-Id: Idb8b4a86d3caed89f69cde1607886face103cf6a
* dont mutate bind_arguments incoming dictionaryMike Bayer2022-10-071-0/+47
| | | | | | | | | | | | | | | The :paramref:`_orm.Session.execute.bind_arguments` dictionary is no longer mutated when passed to :meth:`_orm.Session.execute` and similar; instead, it's copied to an internal dictionary for state changes. Among other things, this fixes and issue where the "clause" passed to the :meth:`_orm.Session.get_bind` method would be incorrectly referring to the :class:`_sql.Select` construct used for the "fetch" synchronization strategy, when the actual query being emitted was a :class:`_dml.Delete` or :class:`_dml.Update`. This would interfere with recipes for "routing sessions". Fixes: #8614 Change-Id: I8d237449485c9bbf41db2b29a34b6136aa43b7bc
* implement write-only colletions, typing for dynamicMike Bayer2022-10-062-0/+72
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | For 2.0, we provide a truly "larger than memory collection" implementation, a write-only collection that will never under any circumstances implicitly load the entire collection, even during flush. This is essentially a much more "strict" version of the "dynamic" loader, which in fact has a lot of scenarios that it loads the full backing collection into memory, mostly defeating its purpose. Typing constructs are added that support both the new feature WriteOnlyMapping as well as the legacy feature DynamicMapping. These have been integrated with "annotion based mapping" so that relationship() uses these annotations to configure the loader strategy as well. additional changes: * the docs triggered a conflict in hybrid's "transformers" section, this section is hard-coded to Query using a pattern that doesnt seem to have any use and isn't part of the current select() interface, so just removed this section * As the docs for WriteOnlyMapping are very long, collections.rst is broken up into two pages now. Fixes: #6229 Fixes: #7123 Change-Id: I6929f3da6e441cad92285e7309030a9bac4e429d
* ORM bulk insert via executeMike Bayer2022-09-245-0/+5600
* ORM Insert now includes "bulk" mode that will run essentially the same process as session.bulk_insert_mappings; interprets the given list of values as ORM attributes for key names * ORM UPDATE has a similar feature, without RETURNING support, for session.bulk_update_mappings * Added support for upserts to do RETURNING ORM objects as well * ORM UPDATE/DELETE with list of parameters + WHERE criteria is a not implemented; use connection * ORM UPDATE/DELETE defaults to "auto" synchronize_session; use fetch if RETURNING is present, evaluate if not, as "fetch" is much more efficient (no expired object SELECT problem) and less error prone if RETURNING is available UPDATE: howver this is inefficient! please continue to use evaluate for simple cases, auto can move to fetch if criteria not evaluable * "Evaluate" criteria will now not preemptively unexpire and SELECT attributes that were individually expired. Instead, if evaluation of the criteria indicates that the necessary attrs were expired, we expire the object completely (delete) or expire the SET attrs unconditionally (update). This keeps the object in the same unloaded state where it will refresh those attrs on the next pass, for this generally unusual case. (originally #5664) * Core change! update/delete rowcount comes from len(rows) if RETURNING was used. SQLite at least otherwise did not support this. adjusted test_rowcount accordingly * ORM DELETE with a list of parameters at all is also a not implemented as this would imply "bulk", and there is no bulk_delete_mappings (could be, but we dont have that) * ORM insert().values() with single or multi-values translates key names based on ORM attribute names * ORM returning() implemented for insert, update, delete; explcit returning clauses now interpret rows in an ORM context, with support for qualifying loader options as well * session.bulk_insert_mappings() assigns polymorphic identity if not set. * explicit RETURNING + synchronize_session='fetch' is now supported with UPDATE and DELETE. * expanded return_defaults() to work with DELETE also. * added support for composite attributes to be present in the dictionaries used by bulk_insert_mappings and bulk_update_mappings, which is also the new ORM bulk insert/update feature, that will expand the composite values into their individual mapped attributes the way they'd be on a mapped instance. * bulk UPDATE supports "synchronize_session=evaluate", is the default. this does not apply to session.bulk_update_mappings, just the new version * both bulk UPDATE and bulk INSERT, the latter with or without RETURNING, support *heterogenous* parameter sets. session.bulk_insert/update_mappings did this, so this feature is maintained. now cursor result can be both horizontally and vertically spliced :) This is now a long story with a lot of options, which in itself is a problem to be able to document all of this in some way that makes sense. raising exceptions for use cases we haven't supported is pretty important here too, the tradition of letting unsupported things just not work is likely not a good idea at this point, though there are still many cases that aren't easily avoidable Fixes: #8360 Fixes: #7864 Fixes: #7865 Change-Id: Idf28379f8705e403a3c6a937f6a798a042ef2540