summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql/elements.py
Commit message (Collapse)AuthorAgeFilesLines
* support parameters in all ORM insert modesMike Bayer2023-04-261-0/+22
| | | | | | | | | | | | | | | | | | | | 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
* Merge "add deterministic imv returning ordering using sentinel columns" into ↵mike bayer2023-04-211-2/+5
|\ | | | | | | main
| * add deterministic imv returning ordering using sentinel columnsMike Bayer2023-04-211-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* | Define type hints for remaining column operatorsMartijn Pieters2023-04-181-0/+43
|/ | | | | | | | | | | | | | | | | | Added typing information for recently added operators :meth:`.ColumnOperators.icontains`, :meth:`.ColumnOperators.istartswith`, :meth:`.ColumnOperators.iendswith`, and bitwise operators :meth:`.ColumnOperators.bitwise_and`, :meth:`.ColumnOperators.bitwise_or`, :meth:`.ColumnOperators.bitwise_xor`, :meth:`.ColumnOperators.bitwise_not`, :meth:`.ColumnOperators.bitwise_lshift` :meth:`.ColumnOperators.bitwise_rshift`. Pull request courtesy Martijn Pieters. Fixes: #9650 Closes: #9652 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9652 Pull-request-sha: 005c56848af8cff6bb19f71541873027f141eb6e Change-Id: I2fa06eb42ce668df9d9c760d233906f87484dd12
* Remove old versionadded and versionchangedFederico Caselli2023-04-121-19/+0
| | | | | | | Removed versionadded and versionchanged for version prior to 1.2 since they are no longer useful. Change-Id: I5c53d1188bc5fec3ab4be39ef761650ed8fa6d3e
* use clone, not constructor, in BindParameter.render_literal_execute()Mike Bayer2023-03-221-6/+3
| | | | | | | | | | | | | Fixed issue where the :meth:`_sql.BindParameter.render_literal_execute` method would fail when called on a parameter that also had ORM annotations associated with it. In practice, this would be observed as a failure of SQL compilation when using some combinations of a dialect that uses "FETCH FIRST" such as Oracle along with a :class:`_sql.Select` construct that uses :meth:`_sql.Select.limit`, within some ORM contexts, including if the statement were embedded within a relationship primaryjoin expression. Fixes: #9526 Change-Id: I2f512b6760a90293d274e60b06a891f10b276ecc
* Use independent TypeVar for ColumnElement.castMike Bayer2023-03-081-1/+1
| | | | | | | | | | Fixed typing issue where :meth:`.ColumnElement.cast` did not allow a :class:`.TypeEngine` argument independent of the type of the :class:`.ColumnElement` itself, which is the purpose of :meth:`.ColumnElement.cast`. Fixes: #9451 Change-Id: I68119c6a9e8bf896715eea79be2b4f36b1c141de
* TextualSelect is ReturnsRowsRoleMike Bayer2023-03-021-6/+18
| | | | | | | | | | Fixed typing bug where :meth:`_sql.Select.from_statement` would not accept :func:`_sql.text` or :class:`.TextualSelect` objects as a valid type. Additionally repaired the :class:`.TextClause.columns` method to have a return type, which was missing. Fixes: #9398 Change-Id: I627fc33bf83365e1c7f7c6ed29ea387dfd4a57d8
* Fix coercion issue for tuple bindparamsmike bayer2023-02-151-3/+7
| | | | | | | | | | | | Fixed issue where element types of a tuple value would be hardcoded to take on the types from a compared-to tuple, when the comparison were using the :meth:`.ColumnOperators.in_` operator. This was inconsistent with the usual way that types are determined for a binary expression, which is that the actual element type on the right side is considered first before applying the left-hand-side type. Fixes: #9313 Change-Id: Ia8874c09682a6512fcf4084cf14481024959c461
* apply self_group to all elements of multi-expressionMike Bayer2023-02-091-8/+9
| | | | | | | | | | | Fixed critical regression in SQL expression formulation in the 2.0 series due to :ticket:`7744` which improved support for SQL expressions that contained many elements against the same operator repeatedly; parenthesis grouping would be lost with expression elements beyond the first two elements. Fixes: #9271 Change-Id: Ib6ed5b71efe0f6816dab75bda622297fc89e3b49
* Remove `typing.Self` workaroundYurii Karabas2023-02-081-26/+12
| | | | | | | | | | | | Remove ``typing.Self`` workaround, now using :pep:`673` for most methods that return ``Self``. Pull request courtesy Yurii Karabas. Fixes: #9254 Closes: #9255 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9255 Pull-request-sha: 2947df8ada79f5c3afe9c838e65993302199c2f7 Change-Id: Ic32015ad52e95a61f3913d43ea436aa9402804df
* Dedicated bitwise operatorsjazzthief2023-02-061-0/+15
| | | | | | | | | | | | | Added a full suite of new SQL bitwise operators, for performing database-side bitwise expressions on appropriate data values such as integers, bit-strings, and similar. Pull request courtesy Yegor Statkevich. Fixes: #8780 Closes: #9204 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9204 Pull-request-sha: a4541772a6a784f9161ad78ef84d2ea7a62fa8de Change-Id: I4c70e80f9548dcc1b4e3dccd71bd59d51d3ed46e
* Set correct type annotations for ColumnElement.castYurii Karabas2023-01-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | <!-- Provide a general summary of your proposed changes in the Title field above --> Fixes: #9156 ### Description <!-- Describe your changes in detail --> ### Checklist <!-- go over following points. check them with an `x` if they do apply, (they turn into clickable checkboxes once the PR is submitted, so no need to do everything at once) --> This pull request is: - [ ] A documentation / typographical error fix - Good to go, no issue or tests are needed - [x] A short code fix - please include the issue number, and create an issue if none exists, which must include a complete example of the issue. one line code fixes without an issue and demonstration will not be accepted. - Please include: `Fixes: #<issue number>` in the commit message - please include tests. one line code fixes without tests will not be accepted. - [ ] A new feature implementation - please include the issue number, and create an issue if none exists, which must include a complete example of how the feature would look. - Please include: `Fixes: #<issue number>` in the commit message - please include tests. **Have a nice day!** Closes: #9157 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9157 Pull-request-sha: 321dac184ee0d317296a689d7c8e47bf1464bcce Change-Id: I99fe759a21de910f34bae3bb919e82cd08969e81
* add typing to legacy operatorsMike Bayer2023-01-261-0/+27
| | | | | | | | | Added typing to legacy operators such as ``isnot()``, ``notin_()``, etc. which previously were referencing the newer operators but were not themselves typed. Fixes: #9148 Change-Id: I3ad7d75d89ec13c9f45063033ecff69d610c72ca
* Merge "typing updates" into mainmike bayer2023-01-201-26/+49
|\
| * typing updatesMike Bayer2023-01-201-26/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The :meth:`_sql.ColumnOperators.in_` and :meth:`_sql.ColumnOperators.not_in_` are typed to include ``Iterable[Any]`` rather than ``Sequence[Any]`` for more flexibility in argument type. The :func:`_sql.or_` and :func:`_sql.and_` from a typing perspective require the first argument to be present, however these functions still accept zero arguments which will emit a deprecation warning at runtime. Typing is also added to support sending the fixed literal ``False`` for :func:`_sql.or_` and ``True`` for :func:`_sql.and_` as the first argument only, however the documentation now indicates sending the :func:`_sql.false` and :func:`_sql.true` constructs in these cases as a more explicit approach. Fixed typing issue where iterating over a :class:`_orm.Query` object was not correctly typed. Fixes: #9122 Fixes: #9123 Fixes: #9125 Change-Id: I500e3e1b826717b3dd49afa1e682c3c8279c9226
* | implement basic typing for lambda elementsMike Bayer2023-01-191-3/+3
|/ | | | | | | | | | | | | | | | | These weren't working at all, so fixed things up and added a test suite. Keeping things very basic with Any returns etc. as having more specific return types starts making it too cumbersome to write end-user code. Corrected the type passed for "lambda statements" so that a plain lambda is accepted by mypy, pyright, others without any errors about argument types. Additionally implemented typing for more of the public API for lambda statements and ensured :class:`.StatementLambdaElement` is part of the :class:`.Executable` hierarchy so it's typed as accepted by :meth:`_engine.Connection.execute`. Fixes: #9120 Change-Id: Ia7fa34e5b6e43fba02c8f94ccc256f3a68a1f445
* Merge "Type annotations for sqlalchemy.sql.selectable" into mainmike bayer2023-01-131-2/+6
|\
| * Type annotations for sqlalchemy.sql.selectableDzmitar2023-01-131-2/+6
| | | | | | | | | | | | | | | | | | Co-authored-by: Mike Bayer <mike_mp@zzzcomputing.com> Closes: #9028 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/9028 Pull-request-sha: e2f8ddeac0b08feaad917285e988acf1e9465a26 Change-Id: I5caad31bfeeed2d224657a55f067ba1d86b8733f
* | Fixes related to improved sql formattingFederico Caselli2023-01-121-4/+8
|/ | | | | | Follow up of I07b72e6620bb64e329d6b641afa27631e91c4f16 Change-Id: I1f61974bf9cdc3da5317e546d4f9b649c2029e4d
* replace @decorated_property decoratorMike Bayer2023-01-121-2/+4
| | | | | | | | | | | | | This decorator is no longer necessary as of Mypy 0.981 [1]. In current mypy versions, we require direct use of `@property` for return types of these methods to be recognized [1] https://github.com/python/mypy/issues/1362 Change-Id: Ibc36083dec854c5f9140a9b621e9bf9d5bb4fb61
* happy new year 2023Mike Bayer2023-01-031-1/+1
| | | | Change-Id: I625af65b3fb1815b1af17dc2ef47dd697fdc3fb1
* Order_by and group_by accept labelsFederico Caselli2022-12-031-2/+3
| | | | | | Improve typing to accept labels in ordey_by mand group_by. Change-Id: I33e5d6f64633d39a220108d412ef84d6478b25e6
* update for mypy 1.0 devFederico Caselli2022-11-291-3/+0
| | | | | | | | | | | | | | | | As I need dmypy to work without facing [1], I am running the latest build of mypy which seems so far to finally not have that issue. update constructs that latest mypy is being more picky about, including better typing for the _NONE_NAME symbol used in constraints (porting those elements from the Enum patch at I15ac3daee770408b5795746f47c1bbd931b7d26d) [1] https://github.com/python/mypy/issues/12744 Change-Id: Ib3f56787fa65ea9bb2e6a0bccc4d99f54c516dad
* Implement ScalarValueFederico Caselli2022-11-261-3/+6
| | | | | | | | | | | | | | Added :class:`_expression.ScalarValues` that can be used as a column element allowing using :class:`_expression.Values` inside IN clauses or in conjunction with ``ANY`` or ``ALL`` collection aggregates. This new class is generated using the method :meth:`_expression.Values.scalar_values`. The :class:`_expression.Values` instance is now coerced to a :class:`_expression.ScalarValues` when used in a ``IN`` or ``NOT IN`` operation. Fixes: #6289 Change-Id: Iac22487ccb01553684b908e54d01c0687fa739f1
* add common base class for all SQL col expression objectsMike Bayer2022-11-211-1/+21
| | | | | | | | | | | Added a new type :class:`.SQLColumnExpression` which may be indicated in user code to represent any SQL column oriented expression, including both those based on :class:`.ColumnElement` as well as on ORM :class:`.QueryableAttribute`. This type is a real class, not an alias, so can also be used as the foundation for other objects. Fixes: #8847 Change-Id: I3161bdff1c9f447793fce87864e1774a90cd4146
* Try running pyupgrade on the codeFederico Caselli2022-11-161-9/+9
| | | | | | | | 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
* perf improvements related to corresponding_column (2)Mike Bayer2022-11-151-12/+40
| | | | | | | | | | | | | | | | | commit two of two. this reorganizes ColumnCollection to build a new index up front that's used to optimize the corresponding_column() method. Additional performance enhancements within ORM-enabled SQL statements, specifically targeting callcounts within the construction of ORM statements, using combinations of :func:`_orm.aliased` with :func:`_sql.union` and similar "compound" constructs, in addition to direct performance improvements to the ``corresponding_column()`` internal method that is used heavily by the ORM by constructs like :func:`_orm.aliased` and similar. Fixes: #8796 Change-Id: I4a76788007d5a802b9a4081e6a0f6e4b52497b50
* ensure anon_map is passed for most annotated traversalsMike Bayer2022-11-111-2/+25
| | | | | | | | | | | | | | | | | | | | | | | | 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
* Improve typings of execution optionsFederico Caselli2022-11-021-4/+4
| | | | | Fixes: #8605 Change-Id: I4aec83b9f321462427c3f4ac941c3b272255c088
* apply basic escaping to anon_labels unconditionallyMike Bayer2022-10-271-1/+6
| | | | | | | | | | | | Fixed issue which prevented the :func:`_sql.literal_column` construct from working properly within the context of a :class:`.Select` construct as well as other potential places where "anonymized labels" might be generated, if the literal expression contained characters which could interfere with format strings, such as open parenthesis, due to an implementation detail of the "anonymous label" structure. Fixes: #8724 Change-Id: I3089124fbd055a011c8a245964258503b717d941
* remove should_nest behavior for contains_eager()Mike Bayer2022-09-231-1/+1
| | | | | | | | | | | | | | | | | | | Fixed regression for 1.4 in :func:`_orm.contains_eager` where the "wrap in subquery" logic of :func:`_orm.joinedload` would be inadvertently triggered for use of the :func:`_orm.contains_eager` function with similar statements (e.g. those that use ``distinct()``, ``limit()`` or ``offset()``). This is not appropriate for :func:`_orm.contains_eager` which has always had the contract that the user-defined SQL statement is unmodified with the exception of adding the appropriate columns. Also includes an adjustment to the assertion in Label._make_proxy() which was there to prevent a fixed label name from being anonymized; if the label is already anonymous, the change should proceed. This logic was being hit before the contains_eager behavior was adjusted. With the adjustment, this code is not used. Fixes: #8569 Change-Id: I161e65041c0162fd2b83cbef40f57a50fcfaf0fd
* implement icontains, istartswith, iendswith operatorsMatias Martinez Rebori2022-09-081-0/+2
| | | | | | | | | | | | | | | | | | | | Added long-requested case-insensitive string operators :meth:`_sql.ColumnOperators.icontains`, :meth:`_sql.ColumnOperators.istartswith`, :meth:`_sql.ColumnOperators.iendswith`, which produce case-insensitive LIKE compositions (using ILIKE on PostgreSQL, and the LOWER() function on all other backends) to complement the existing LIKE composition operators :meth:`_sql.ColumnOperators.contains`, :meth:`_sql.ColumnOperators.startswith`, etc. Huge thanks to Matias Martinez Rebori for their meticulous and complete efforts in implementing these new methods. Fixes: #3482 Closes: #8496 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8496 Pull-request-sha: 7287e2c436959fac4fef022f359fcc73d1528211 Change-Id: I9fcdd603716218067547cc92a2b07bd02a2c366b
* update quoted_name docMike Bayer2022-08-041-1/+2
| | | | | Fixes: #8339 Change-Id: If78bc9babfdc6a4dde4e65d72858ac7a402cbb4d
* Remove all `__nonzero__` methods (#8308)Nikita Sobolev2022-07-301-2/+0
|
* support "SELECT *" for ORM queriesMike Bayer2022-07-101-0/+9
| | | | | | | | | | | | | | | | | | A :func:`_sql.select` construct that is passed a sole '*' argument for ``SELECT *``, either via string, :func:`_sql.text`, or :func:`_sql.literal_column`, will be interpreted as a Core-level SQL statement rather than as an ORM level statement. This is so that the ``*``, when expanded to match any number of columns, will result in all columns returned in the result. the ORM- level interpretation of :func:`_sql.select` needs to know the names and types of all ORM columns up front which can't be achieved when ``'*'`` is used. If ``'*`` is used amongst other expressions simultaneously with an ORM statement, an error is raised as this can't be interpreted correctly by the ORM. Fixes: #8235 Change-Id: Ic8e84491e14acdc8570704eadeaeaf6e16b1e870
* Merge "fix race conditions in lambda statements" into mainmike bayer2022-06-091-1/+8
|\
| * fix race conditions in lambda statementsMike Bayer2022-06-081-1/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixed multiple observed race conditions related to :func:`.lambda_stmt`, including an initial "dogpile" issue when a new Python code object is initially analyzed among multiple simultaneous threads which created both a performance issue as well as some internal corruption of state. Additionally repaired observed race condition which could occur when "cloning" an expression construct that is also in the process of being compiled or otherwise accessed in a different thread due to memoized attributes altering the ``__dict__`` while iterated, for Python versions prior to 3.10; in particular the lambda SQL construct is sensitive to this as it holds onto a single statement object persistently. The iteration has been refined to use ``dict.copy()`` with or without an additional iteration instead. Fixes: #8098 Change-Id: I4e0b627bfa187f1780dc68ec81b94db1c78f846a
* | migrate labels to new tutorialMike Bayer2022-06-071-3/+3
|/ | | | | | | other org changes and some sections from old tutorial ported to new tutorial. Change-Id: Ic0fba60ec82fff481890887beef9ed0fa271875a
* Merge "propagate proxy_key from WrapsColumnExpression" into mainmike bayer2022-06-011-0/+8
|\
| * propagate proxy_key from WrapsColumnExpressionMike Bayer2022-06-011-0/+8
| | | | | | | | | | | | | | | | | | | | | | | | | | this allows cast() of a label() to propagate the proxy key outwards in the same way that it apparently works at the SQL level. This is stuffing even more rules into naming so basically seeing how far we can go without other cases starting to fail. Fixes: #8084 Change-Id: I20bd97dae798fee6492334c06934e807d0f269ef
* | add backend agnostic UUID datatypeMike Bayer2022-06-011-5/+18
|/ | | | | | | | | | | | | | | | | | | | Added new backend-agnostic :class:`_types.Uuid` datatype generalized from the PostgreSQL dialects to now be a core type, as well as migrated :class:`_types.UUID` from the PostgreSQL dialect. Thanks to Trevor Gross for the help on this. also includes: * corrects some missing behaviors in the suite literal fixtures test where row round trips weren't being correctly asserted. * fixes some of the ISO literal date rendering added in 952383f9ee0 for #5052 to truncate datetime strings for date/time datatypes in the same way that drivers typically do for bound parameters; this was not working fully and wasn't caught by the broken test fixture Fixes: #7212 Change-Id: I981ac6d34d278c18281c144430a528764c241b04
* revenge of pep 484Mike Bayer2022-05-151-5/+13
| | | | | | trying to get remaining must-haves for ORM Change-Id: I66a3ecbbb8e5ba37c818c8a92737b576ecf012f7
* inline mypy config; files ignoring type errors for the momentMike Bayer2022-04-281-0/+1
| | | | | | | | | | | | | | | | | | | to simplify pyproject.toml change the remaining files that aren't going to be typed on this first pass (unless of course someone wants to type some of these) to include # mypy: ignore-errors. for the moment, only a handful of ORM modules are to have more type checking implemented. It's important that ignore-errors is used and not "# type: ignore", as in the latter case, mypy doesn't even read the existing types in the file, which makes it impossible to type any files that refer to those modules at all. to simplify ongoing typing work use inline mypy config for remaining files that are "done" for now, indicating the level of type checking they currently have. Change-Id: I98669c1a305c2f0adba85d10b5425541f3fe9533
* pep484 ORM / SQL result supportMike Bayer2022-04-271-12/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | after some experimentation it seems mypy is more amenable to the generic types being fully integrated rather than having separate spin-off types. so key structures like Result, Row, Select become generic. For DML Insert, Update, Delete, these are spun into type-specific subclasses ReturningInsert, ReturningUpdate, ReturningDelete, which is fine since the "row-ness" of these constructs doesn't happen until returning() is called in any case. a Tuple based model is then integrated so that these objects can carry along information about their return types. Overloads at the .execute() level carry through the Tuple from the invoked object to the result. To suit the issue of AliasedClass generating attributes that are dynamic, experimented with a custom subclass AsAliased, but then just settled on having aliased() lie to the type checker and return `Type[_O]`, essentially. will need some type-related accessors for with_polymorphic() also. Additionally, identified an issue in Update when used "mysql style" against a join(), it basically doesn't work if asked to UPDATE two tables on the same column name. added an error message to the specific condition where it happens with a very non-specific error message that we hit a thing we can't do right now, suggest multi-table update as a possible cause. Change-Id: I5eff7eefe1d6166ee74160b2785c5e6a81fa8b95
* pep-484: ORM public API, constructorsMike Bayer2022-04-201-14/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | for the moment, abandoning using @overload with relationship() and mapped_column(). The overloads are very difficult to get working at all, and the overloads that were there all wouldn't pass on mypy. various techniques of getting them to "work", meaning having right hand side dictate what's legal on the left, have mixed success and wont give consistent results; additionally, it's legal to have Optional / non-optional independent of nullable in any case for columns. relationship cases are less ambiguous but mypy was not going along with things. we have a comprehensive system of allowing left side annotations to drive the right side, in the absense of explicit settings on the right. so type-centric SQLAlchemy will be left-side driven just like dataclasses, and the various flags and switches on the right side will just not be needed very much. in other matters, one surprise, forgot to remove string support from orm.join(A, B, "somename") or do deprecations for it in 1.4. This is a really not-directly-used structure barely mentioned in the docs for many years, the example shows a relationship being used, not a string, so we will just change it to raise the usual error here. Change-Id: Iefbbb8d34548b538023890ab8b7c9a5d9496ec6e
* Merge "pep484: schema API" into mainmike bayer2022-04-151-17/+47
|\
| * pep484: schema APIMike Bayer2022-04-151-17/+47
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | implement strict typing for schema.py this module has lots of public API, lots of old decisions and very hard to follow construction sequences in many cases, and is also where we get a lot of new feature requests, so strict typing should help keep things clean. among improvements here, fixed the pool .info getters and also figured out how to get ColumnCollection and related to be covariant so that we may set them up as returning Column or ColumnClause without any conflicts. DDL was affected, noting that superclasses of DDLElement (_DDLCompiles, added recently) can now be passed into "ddl_if" callables; reorganized ddl into ExecutableDDLElement as a new name for DDLElement and _DDLCompiles renamed to BaseDDLElement. setting up strict also located an API use case that is completely broken, which is connection.execute(some_default) returns a scalar value. This case has been deprecated and new paths have been set up so that connection.scalar() may be used. This likely wasn't possible in previous versions because scalar() would assume a CursorResult. The scalar() change also impacts Session as we have explicit support (since someone had reported it as a regression) for session.execute(Sequence()) to work. They will get the same deprecation message (which omits the word "Connection", just uses ".execute()" and ".scalar()") and they can then use Session.scalar() as well. Getting this to type correctly while still supporting ORM use cases required some refactoring, and I also set up a keyword only delimeter for Session.execute() and related as execution_options / bind_arguments should always be keyword only, applied these changes to AsyncSession as well. Additionally simpify Table __init__ now that we are Python 3 only, we can have positional plus explicit kwargs finally. Simplify Column.__init__ as well again taking advantage of kw only arguments. Fill in most/all __init__ methods in sqltypes.py as the constructor for types is most of the API. should likely do this for dialect-specific types as well. Apply _InfoType for all info attributes as should have been done originally and update descriptor decorators. Change-Id: I3f9f8ff3f1c8858471ff4545ac83d68c88107527
* | implement multi-element expression constructsMike Bayer2022-04-131-30/+197
|/ | | | | | | | | | | | | | | | | | | | | | Improved the construction of SQL binary expressions to allow for very long expressions against the same associative operator without special steps needed in order to avoid high memory use and excess recursion depth. A particular binary operation ``A op B`` can now be joined against another element ``op C`` and the resulting structure will be "flattened" so that the representation as well as SQL compilation does not require recursion. To implement this more cleanly, the biggest change here is that column-oriented lists of things are broken away from ClauseList in a new class ExpressionClauseList, that also forms the basis of BooleanClauseList. ClauseList is still used for the generic "comma-separated list" of things such as Tuple and things like ORDER BY, as well as in some API endpoints. Also adds __slots__ to the TypeEngine-bound Comparator classes. Still can't really do __slots__ on ClauseElement. Fixes: #7744 Change-Id: I81a8ceb6f8f3bb0fe52d58f3cb42e4b6c2bc9018
* update flake8 noqa skips with proper syntaxFederico Caselli2022-04-111-3/+3
| | | | Change-Id: I42ed77f559e3ee5b8c600d98457ee37803ef0ea6