summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/testing
Commit message (Collapse)AuthorAgeFilesLines
* ensure event handlers called for all do_pingticket_5648Mike Bayer2023-03-011-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | The support for pool ping listeners to receive exception events via the :meth:`.ConnectionEvents.handle_error` event added in 2.0.0b1 for :ticket:`5648` failed to take into account dialect-specific ping routines such as that of MySQL and PostgreSQL. The dialect feature has been reworked so that all dialects participate within event handling. Additionally, a new boolean element :attr:`.ExceptionContext.is_pre_ping` is added which identifies if this operation is occurring within the pre-ping operation. For this release, third party dialects which implement a custom :meth:`_engine.Dialect.do_ping` method can opt in to the newly improved behavior by having their method no longer catch exceptions or check exceptions for "is_disconnect", instead just propagating all exceptions outwards. Checking the exception for "is_disconnect" is now done by an enclosing method on the default dialect, which ensures that the event hook is invoked for all exception scenarios before testing the exception as a "disconnect" exception. If an existing ``do_ping()`` method continues to catch exceptions and check "is_disconnect", it will continue to work as it did previously, but ``handle_error`` hooks will not have access to the exception if it isn't propagated outwards. Fixes: #5648 Change-Id: I6535d5cb389e1a761aad8c37cfeb332c548b876d
* prevent float tests from running on asyncmyMike Bayer2023-02-152-4/+16
| | | | | | | | asyncmy 0.2.7 has had a loss in float precision for even very low numbers of significant digits. Change-Id: Iec6d2650943eeaa8e854f21990f6565d73331f8c References: https://github.com/long2ice/asyncmy/issues/56
* add error code 1049 for mysql has_tableMike Bayer2023-02-061-0/+9
| | | | | | | | | | | | | | Fixed regression caused by issue :ticket:`9058` which adjusted the MySQL dialect's ``has_table()`` to again use "DESCRIBE", where the specific error code raised by MySQL version 8 when using a non-existent schema name was unexpected and failed to be interpreted as a boolean result. Fixed the SQLite dialect's ``has_table()`` function to correctly report False for queries that include a non-None schema name for a schema that doesn't exist; previously, a database error was raised. Fixes: #9251 Change-Id: I5ef9cf0887865c3c521d88bca0ba18954a108241
* Merge "fix incorrect use of testing.future()" into mainmike bayer2023-01-261-3/+2
|\
| * fix incorrect use of testing.future()Mike Bayer2023-01-251-3/+2
| | | | | | | | | | | | | | this has been emitting a warning probably for a long time Change-Id: I44a6766b5e92d14ce6bbb5a90ab52648f877afc2
* | add set_shard_id() loader option for horizontal shardMike Bayer2023-01-251-11/+12
|/ | | | | | | | | | | | | | Added new option to horizontal sharding API :class:`_horizontal.set_shard_id` which sets the effective shard identifier to query against, for both the primary query as well as for all secondary loaders including relationship eager loaders as well as relationship and column lazy loaders. Modernize sharding examples with new-style mappings, add new asyncio example. Fixes: #7226 Fixes: #7028 Change-Id: Ie69248060c305e8de04f75a529949777944ad511
* fix stringify for CreateSchemaMike Bayer2023-01-241-0/+2
| | | | | | | | Fixed stringify for a the :class:`.CreateSchema` DDL construct, which would fail with an ``AttributeError`` when stringified without a dialect. Fixes: #7664 Change-Id: Ifc1769604bc5219c060f5112f7bdea0f780f1a1c
* happy new year 2023Mike Bayer2023-01-0316-16/+16
| | | | Change-Id: I625af65b3fb1815b1af17dc2ef47dd697fdc3fb1
* add exclusion for unusual chars in column namesMike Bayer2022-12-192-0/+12
| | | | | | | | | | | | Added new exclusion rule for third party dialects called ``unusual_column_name_characters``, which can be "closed" for third party dialects that don't support column names with unusual characters such as dots, slashes, or percent signs in them, even if the name is properly quoted. Fixes: #9002 Change-Id: I44b765df4c73ce5ec1907d031fd9c89761fd99d1 References: #8993
* Merge "ensure all visit methods accept **kw" into mainmike bayer2022-12-171-0/+51
|\
| * ensure all visit methods accept **kwMike Bayer2022-12-161-0/+51
| | | | | | | | | | | | | | | | | | | | Added test support to ensure that all compiler ``visit_xyz()`` methods across all :class:`.Compiler` implementations in SQLAlchemy accept a ``**kw`` parameter, so that all compilers accept additional keyword arguments under all circumstances. Fixes: #8988 Change-Id: I1cefc313e4e64a10ee7dd14400137fbe02ce9523
* | add eager_defaults="auto" for insertsMike Bayer2022-12-152-15/+39
|/ | | | | | | | | | | | | | Added a new default value for the :paramref:`.Mapper.eager_defaults` parameter "auto", which will automatically fetch table default values during a unit of work flush, if the dialect supports RETURNING for the INSERT being run, as well as :ref:`insertmanyvalues <engine_insertmanyvalues>` available. Eager fetches for server-side UPDATE defaults, which are very uncommon, continue to only take place if :paramref:`.Mapper.eager_defaults` is set to ``True``, as there is no batch-RETURNING form for UPDATE statements. Fixes: #8889 Change-Id: I84b91092a37c4cd216e060513acde3eb0298abe9
* Specify view columns in HasTableTestGord Thompson2022-12-091-4/+7
| | | | | | | | | Fixes: #8960 Avoid test errors on databases that do not support CREATE VIEW vv AS SELECT * FROM Change-Id: Ic9e892aa4466030b9b325c11228dad15cf59a258
* fix construct_params() for render_postcompile; add new APIMike Bayer2022-12-081-3/+23
| | | | | | | | | | | | | | | | | | | | | The :meth:`.SQLCompiler.construct_params` method, as well as the :attr:`.SQLCompiler.params` accessor, will now return the exact parameters that correspond to a compiled statement that used the ``render_postcompile`` parameter to compile. Previously, the method returned a parameter structure that by itself didn't correspond to either the original parameters or the expanded ones. Passing a new dictionary of parameters to :meth:`.SQLCompiler.construct_params` for a :class:`.SQLCompiler` that was constructed with ``render_postcompile`` is now disallowed; instead, to make a new SQL string and parameter set for an alternate set of parameters, a new method :meth:`.SQLCompiler.construct_expanded_state` is added which will produce a new expanded form for the given parameter set, using the :class:`.ExpandedState` container which includes a new SQL statement and new parameter dictionary, as well as a positional parameter tuple. Fixes: #6114 Change-Id: I9874905bb90f86799b82b244d57369558b18fd93
* Rewrite positional handling, test for "numeric"Federico Caselli2022-12-053-10/+34
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* disallow same-named columns, unchecked replacement in TableMike Bayer2022-12-042-6/+24
| | | | | | | | | | | | | | | Fixed issue where table reflection using :paramref:`.Table.extend_existing` would fail to deduplicate a same-named column if the existing :class:`.Table` used a separate key. The :paramref:`.Table.autoload_replace` parameter would allow the column to be skipped but under no circumstances should a :class:`.Table` ever have the same-named column twice. Additionally, changed deprecation warnings to exceptions as were implemented in I1d58c8ebe081079cb669e7ead60886ffc1b1a7f5 . Fixes: #8925 Change-Id: I83d0f8658177a7ffbb06e01dbca91377d1a98d49
* add spaces, leading underscore to oracle checksMike Bayer2022-12-021-3/+63
| | | | | | | | | | | | Expand the test suite from #8708 which unfortunately did not exercise the bound parameter codepaths completely. Continued fixes for Oracle fix :ticket:`8708` released in 1.4.43 where bound parameter names that start with underscores, which are disallowed by Oracle, were still not being properly escaped in all circumstances. Fixes: #8708 Change-Id: Ic389c09bd7c53b773e5de35f1a18ef20769b92a7
* Fix positional compiling bugsFederico Caselli2022-12-011-3/+61
| | | | | | | | | | | Fixed a series of issues regarding positionally rendered bound parameters, such as those used for SQLite, asyncpg, MySQL and others. Some compiled forms would not maintain the order of parameters correctly, such as the PostgreSQL ``regexp_replace()`` function as well as within the "nesting" feature of the :class:`.CTE` construct first introduced in :ticket:`4123`. Fixes: #8827 Change-Id: I9813ed7c358cc5c1e26725c48df546b209a442cb
* Improve support for enum in mapped classesFederico Caselli2022-11-291-3/+13
| | | | | | | | | | Add a new system by which TypeEngine objects have some say in how the declarative type registry interprets them. The Enum datatype is the primary target for this but it is hoped the system may be useful for other types as well. Fixes: #8859 Change-Id: I15ac3daee770408b5795746f47c1bbd931b7d26d
* add partial index predicate to SQLiteDialect.get_indexes() resultTobias Pfeiffer2022-11-281-1/+8
| | | | | | | | | | | | | Added support for reflection of expression-oriented WHERE criteria included in indexes on the SQLite dialect, in a manner similar to that of the PostgreSQL dialect. Pull request courtesy Tobias Pfeiffer. Fixes: #8804 Closes: #8806 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8806 Pull-request-sha: 539dfcb372360911b69aed2a804698bb1a2220b1 Change-Id: I0e34d47dbe2b9c1da6fce531363084843e5127a3
* add new variation helperMike Bayer2022-11-262-0/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I'm using a lot of @testing.combinations with either a boolean True/False, or a series of string names, each indicating some case to switch on. I want a descriptive name in the test run (not True/False) and I don't want to compare strings. So make a new helper around @combinations that provides an object interface that has booleans inside of it, prints nicely in the test output, raises an error if you name the case incorrectly. Before: test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[False-False-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[False-False-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[False-False-name] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[False-True-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[False-True-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[False-True-name] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[True-False-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[True-False-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[True-False-name] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[True-True-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[True-True-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[True-True-name] PASSED After: test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[not_use_add_property-deferred-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[not_use_add_property-deferred-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[not_use_add_property-deferred-name] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[not_use_add_property-not_deferred-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[not_use_add_property-not_deferred-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[not_use_add_property-not_deferred-name] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[use_add_property-deferred-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[use_add_property-deferred-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[use_add_property-deferred-name] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[use_add_property-not_deferred-both] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[use_add_property-not_deferred-key] PASSED test/orm/declarative/test_typed_mapping.py::MappedColumnTest::test_separate_name[use_add_property-not_deferred-name] PASSED Change-Id: Idde87632581ee69e0f47360966758583dfd8baab
* assert unique constraints received backMike Bayer2022-11-241-0/+2
| | | | | | | in #8867 we can see our existing uq reflection test is broken, not detecting a failure to detect constraints Change-Id: Icada02bc0547c5a3d8c471b80a78a2e72f02647d
* Try running pyupgrade on the codeFederico Caselli2022-11-1610-77/+64
| | | | | | | | 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
* Merge "don't invoke fromclause.c when creating an annotated" into mainmike bayer2022-11-161-0/+12
|\
| * don't invoke fromclause.c when creating an annotatedMike Bayer2022-11-151-0/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The ``aliased()`` constructor calls upon ``__clause_element__()``, which internally annotates a ``FromClause``, like a subquery. This became expensive as ``AnnotatedFromClause`` has for many years called upon ``element.c`` so that the full ``.c`` collection is transferred to the Annotated. Taking this out proved to be challenging. A straight remove seemed to not break any tests except for the one that tested the exact condition. Nevertheless this seemed "spooky" so I instead moved the get of ``.c`` to be in a memoized proxy method. However, that then exposed a recursion issue related to loader_criteria; so the source of that behavior, which was an accidental behavioral artifact, is now made into an explcicit option that loader_criteria uses directly. The accidental behavioral artifact in question is still kind of strange since I was not able to fully trace out how it works, but the end result is that fixing the artifact to be "correct" causes loader_criteria, within the particular test for #7491, creates a select/ subquery structure with a cycle in it, so compilation fails with recursion overflow. The "solution" is to cause the artifact to occur in this case, which is that the ``AnnotatedFromClause`` will have a different ``.c`` collection than its element, which is a subquery. It's not totally clear how a cycle is generated when this is not done. This is commit one of two, which goes through some hoops to make essentially a one-line change. The next commit will rework ColumnCollection to optimize the corresponding_column() method significantly. Fixes: #8796 Change-Id: Id58ae6554db62139462c11a8be7313a3677456ad
* | Repair test in 32bit python builds.Federico Caselli2022-11-121-0/+4
|/ | | | Change-Id: I8287f3e1a975534c8a01a41c9dcc7e5e9f08bb52
* Merge "ensure anon_map is passed for most annotated traversals" into mainmike bayer2022-11-113-0/+75
|\
| * ensure anon_map is passed for most annotated traversalsMike Bayer2022-11-113-0/+75
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We can cache the annotated cache key for Table, but for selectables it's not safe, as it fails to pass the anon_map along and creates many redudant structures in observed test scenario. It is likely safe for a Column that's mapped to a Table also, however this is not implemented here. Will have to see if that part needs adjusting. Fixed critical memory issue identified in cache key generation, where for very large and complex ORM statements that make use of lots of ORM aliases with subqueries, cache key generation could produce excessively large keys that were orders of magnitude bigger than the statement itself. Much thanks to Rollo Konig Brock for their very patient, long term help in finally identifying this issue. Also within TypeEngine objects, when we generate elements for instance variables, skip the None elements at least. this also saves on tuple complexity. Fixes: #8790 Change-Id: I448ddbfb45ae0a648815be8dad4faad7d1977427
* | repair --disable-asyncio parameterMike Bayer2022-11-112-1/+5
|/ | | | | | | | | | | Fixed issue where the ``--disable-asyncio`` parameter to the test suite would fail to not actually run greenlet tests and would also not prevent the suite from using a "wrapping" greenlet for the whole suite. This parameter now ensures that no greenlet or asyncio use will occur within the entire run when set. Fixes: #8793 Change-Id: I87b510846b2cc24413cd54e7b7136e91aad3c309
* Improve typings of execution optionsFederico Caselli2022-11-021-0/+6
| | | | | Fixes: #8605 Change-Id: I4aec83b9f321462427c3f4ac941c3b272255c088
* use only object_id() function for temp tablesMike Barry2022-10-282-13/+69
| | | | | | | | | | | | | | | | | | Fixed issue with :meth:`.Inspector.has_table` when used against a temporary table for the SQL Server dialect would fail an invalid object name error on some Azure variants, due to an unnecessary information schema query that is not supported on those server versions. Pull request courtesy Mike Barry. the patch also fills out test support for has_table() against temp tables, temp views, adding to the has_table() support just added for views in #8700. Fixes: #8714 Closes: #8716 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8716 Pull-request-sha: e2ac7a52e2b09a349a703ba1e1a2911f4d3c0912 Change-Id: Ia73e4e9e977a2d6b7e100abd2f81a8c8777dc9bb
* add Oracle-specific parameter escapes for expanding paramsMike Bayer2022-10-241-0/+9
| | | | | | | | | | | | | | Fixed issue where bound parameter names, including those automatically derived from similarly-named database columns, which contained characters that normally require quoting with Oracle would not be escaped when using "expanding parameters" with the Oracle dialect, causing execution errors. The usual "quoting" for bound parameters used by the Oracle dialect is not used with the "expanding parameters" architecture, so escaping for a large range of characters is used instead, now using a list of characters/escapes that are specific to Oracle. Fixes: #8708 Change-Id: I90c24e48534e1b3a4c222b3022da58159784d91a
* test support for has_table()->view; backport to 1.4Mike Bayer2022-10-231-17/+24
| | | | | | | | | | | | | For 1.4 only; in 2.0 this just refines the test suite a bit. Fixed regression which occurred throughout the 1.4 series where the :meth:`.Inspector.has_table` method, which historically reported on views as well, stopped working for SQL Server. The issue is not present in the 2.0 series which uses a different reflection architecture. Test support is added to ensure ``has_table()`` remains working per spec re: views. Fixes: #8700 Change-Id: I119a91ec07911edb08cf0799234827fec9ea1195
* Merge "further qualify pyodbc setinputsizes types for long stirngs" into mainmike bayer2022-10-192-8/+25
|\
| * further qualify pyodbc setinputsizes types for long stirngsMike Bayer2022-10-182-8/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixed regression caused by SQL Server pyodbc change :ticket:`8177` where we now use ``setinputsizes()`` by default; for VARCHAR, this fails if the character size is greater than 4000 (or 2000, depending on data) characters as the incoming datatype is NVARCHAR, which has a limit of 4000 characters, despite the fact that VARCHAR can handle unlimited characters. Additional pyodbc-specific typing information is now passed to ``setinputsizes()`` when the datatype's size is > 2000 characters. The change is also applied to the :class:`.JSON` type which was also impacted by this issue for large JSON serializations. Fixes: #8661 Change-Id: I07fa873e95dbd2c94f3d286e93e8b3229c3a9807
* | Revert automatic set of sequence start to 1Federico Caselli2022-10-172-16/+53
|/ | | | | | | | | | | | | | | | | The :class:`.Sequence` construct restores itself to the DDL behavior it had prior to the 1.4 series, where creating a :class:`.Sequence` with no additional arguments will emit a simple ``CREATE SEQUENCE`` instruction **without** any additional parameters for "start value". For most backends, this is how things worked previously in any case; **however**, for MS SQL Server, the default value on this database is ``-2**63``; to prevent this generally impractical default from taking effect on SQL Server, the :paramref:`.Sequence.start` parameter should be provided. As usage of :class:`.Sequence` is unusual for SQL Server which for many years has standardized on ``IDENTITY``, it is hoped that this change has minimal impact. Fixes: #7211 Change-Id: I1207ea10c8cb1528a1519a0fb3581d9621c27b31
* implement write-only colletions, typing for dynamicMike Bayer2022-10-062-0/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Merge "`aggregate_order_by` now supports cache generation." into mainmike bayer2022-09-261-0/+108
|\
| * `aggregate_order_by` now supports cache generation.Federico Caselli2022-09-251-0/+108
| | | | | | | | | | | | | | | | | | also adjusted CacheKeyFixture to be a general purpose fixture so that sub-components / dialects can run their own cache key tests. Fixes: #8574 Change-Id: I6c66107856aee11e548d357cea77bceee3e316a0
* | New ORM Query Guide featuring DML supportMike Bayer2022-09-251-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | reviewers: these docs publish periodically at: https://docs.sqlalchemy.org/en/gerrit/4042/orm/queryguide/index.html See the "last generated" timestamp near the bottom of the page to ensure the latest version is up Change includes some other adjustments: * small typing fixes for end-user benefit * removal of a bunch of old examples for patterns that nobody uses or aren't really what we promote now * modernization of some examples, including inheritance Change-Id: I9929daab7797be9515f71c888b28af1209e789ff
* | ORM bulk insert via executeMike Bayer2022-09-243-13/+29
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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
* | implement batched INSERT..VALUES () () for executemanyMike Bayer2022-09-245-0/+220
|/ | | | | | | | | | | | | | | | | | | | the feature is enabled for all built in backends when RETURNING is used, except for Oracle that doesn't need it, and on psycopg2 and mssql+pyodbc it is used for all INSERT statements, not just those that use RETURNING. third party dialects would need to opt in to the new feature by setting use_insertmanyvalues to True. Also adds dialect-level guards against using returning with executemany where we dont have an implementation to suit it. execute single w/ returning still defers to the server without us checking. Fixes: #6047 Fixes: #7907 Change-Id: I3936d3c00003f02e322f2e43fb949d0e6e568304
* Tighten password security by removing `URL.__str__`Yassen Damyanov2022-09-232-3/+6
| | | | | | | | | | | | | | | For improved security, the :class:`_url.URL` object will now use password obfuscation by default when ``str(url)`` is called. To stringify a URL with cleartext password, the :meth:`_url.URL.render_as_string` may be used, passing the :paramref:`_url.URL.render_as_string.hide_password` parameter as ``False``. Thanks to our contributors for this pull request. Fixes: #8567 Closes: #8563 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8563 Pull-request-sha: d1f1127f753849eb70b8d6cc64badf34e1b9219b Change-Id: If756c8073ff99ac83876d9833c8fe1d7c76211f9
* Improve array_agg and Array processingFederico Caselli2022-09-171-0/+11
| | | | | | | | | The :class:`_functions.array_agg` will now set the array dimensions to 1. Improved :class:`_types.ARRAY` processing to accept ``None`` values as value of a multi-array. Fixes: #7083 Change-Id: Iafec4f77fde9719ccc7c8535bf6235dbfbc62102
* Use ``;`` instead of ``select 1`` to ping PostgreSQLFederico Caselli2022-09-151-0/+11
| | | | | Fixes: #8491 Change-Id: I941d2a3cf92e5609e2045a53cec94522340951db
* Use cibuildwheel to create wheelsTrevor Gross2022-08-292-4/+13
| | | | | | | | | | | | | | | | Using cibuildwheel the following wheels are created: - windows x64 and x84 - macos x64 and arm - linux x64 and arm on manylinux and mosulinux (for alpine) - create a pure python wheel (for pypy and other archs) Fixes: #6702 Fixes: #7607 Closes: #7992 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/7992 Pull-request-sha: 61d5e24e5b76c97db73aa2507af7f5c2d3a948fa Change-Id: If0c0b353766e0b61d421789d619eb2b940c08ad0
* include mssql_clustered dialect_options when reflecting - issue #8288John Lennox2022-08-231-4/+9
| | | | | | | | | | | | Implemented reflection of the "clustered index" flag ``mssql_clustered`` for the SQL Server dialect. Pull request courtesy John Lennox. Fixes: #8288 Closes: #8289 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8289 Pull-request-sha: 1bb57352e3e31d8fb7de69ab5e60e5464949f640 Change-Id: Ife367066328f9e47ad823e4098647964a18e21e8
* Update to flake8 5.Federico Caselli2022-07-311-3/+2
| | | | Change-Id: I5a241a70efba68bcea9819ddce6aebc25703e68d
* Reflect expression-based indexes on PostgreSQLFederico Caselli2022-07-284-13/+83
| | | | | | | | | | | The PostgreSQL dialect now supports reflection of expression based indexes. The reflection is supported both when using :meth:`_engine.Inspector.get_indexes` and when reflecting a :class:`_schema.Table` using :paramref:`_schema.Table.autoload_with`. Thanks to immerrr and Aidan Kane for the help on this ticket. Fixes: #7442 Change-Id: I3e36d557235286c0f7f6d8276272ff9225058d48
* update ORM declarative docs for new featuresMike Bayer2022-07-161-0/+6
| | | | | | | I screwed up a rebase or something so this was temporarily in Ic51a12de3358f3a451bd7cf3542b375569499fc1 Change-Id: I847ee1336381221c0112b67854df022edf596b25