summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/dynamic.py
Commit message (Collapse)AuthorAgeFilesLines
* Fix the docstring of AppenerQuery.append() (#9336)Grey Li2023-02-201-2/+2
|
* happy new year 2023Mike Bayer2023-01-031-1/+1
| | | | Change-Id: I625af65b3fb1815b1af17dc2ef47dd697fdc3fb1
* implement write-only colletions, typing for dynamicMike Bayer2022-10-061-378/+109
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* reorganize Mapped[] super outside of MapperPropertyMike Bayer2022-10-051-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | We made all the MapperProperty classes a subclass of Mapped[] to allow declarative mappings to name Mapped[] on the left side. this was cheating a bit because MapperProperty is not actually a descriptor, and the mapping process replaces the object with InstrumentedAttribute at mapping time, which is the actual Mapped[] descriptor. But now in I6929f3da6e441cad92285e7309030a9bac4e429d we are considering making the "cheating" a little more extensive by putting DynamicMapped / WriteOnlyMapped in Relationship's hierarchy, which need a flat out "type: ignore" to work. Instead of pushing more cheats into the core classes, move out the "Declarative"-facing versions of these classes to be typing only: Relationship, Composite, Synonym, and MappedSQLExpression added for ColumnProperty. Keep the internals expressed on the old names, RelationshipProperty, CompositeProperty, SynonymProperty, ColumnProprerty, which will remain "pure" with fully correct typing. then have the typing only endpoints be where the "cheating" and "type: ignores" have to happen, so that these are more or less slightly better forms of "Any". Change-Id: Ied7cc11196c9204da6851f49593d1b1fd2ef8ad8
* Remove all `__nonzero__` methods (#8308)Nikita Sobolev2022-07-301-2/+0
|
* revenge of pep 484Mike Bayer2022-05-151-15/+65
| | | | | | trying to get remaining must-haves for ORM Change-Id: I66a3ecbbb8e5ba37c818c8a92737b576ecf012f7
* pep484: attributes and relatedMike Bayer2022-05-031-3/+5
| | | | | | | also implements __slots__ for QueryableAttribute, InstrumentedAttribute, Relationship.Comparator. Change-Id: I47e823160706fc35a616f1179a06c7864089e5b5
* inline mypy config; files ignoring type errors for the momentMike Bayer2022-04-281-0/+2
| | | | | | | | | | | | | | | | | | | 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
* use annotated entity when adding secondaryMike Bayer2022-03-291-1/+4
| | | | | | | | | | | Fixed regression in "dynamic" loader strategy where the :meth:`_orm.Query.filter_by` method would not be given an appropriate entity to filter from, in the case where a "secondary" table were present in the relationship being queried and the mapping were against something complex such as a "with polymorphic". Fixes: #7868 Change-Id: I3b82eec6485c5a92b56a596da0cfb009e9e67883
* pep-484 for sqlalchemy.event; use future annotationsMike Bayer2022-02-151-0/+2
| | | | | | | | | | __future__.annotations mode allows us to use non-string annotations for argument and return types in most cases, but more importantly it removes a large amount of runtime overhead that would be spent in evaluating the annotations. Change-Id: I2f5b6126fe0019713fc50001be3627b664019ede References: #6810
* establish mypy / typing approach for v2.0Mike Bayer2022-02-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | large patch to get ORM / typing efforts started. this is to support adding new test cases to mypy, support dropping sqlalchemy2-stubs entirely from the test suite, validate major ORM typing reorganization to eliminate the need for the mypy plugin. * New declarative approach which uses annotation introspection, fixes: #7535 * Mapped[] is now at the base of all ORM constructs that find themselves in classes, to support direct typing without plugins * Mypy plugin updated for new typing structures * Mypy test suite broken out into "plugin" tests vs. "plain" tests, and enhanced to better support test structures where we assert that various objects are introspected by the type checker as we expect. as we go forward with typing, we will add new use cases to "plain" where we can assert that types are introspected as we expect. * For typing support, users will be much more exposed to the class names of things. Add these all to "sqlalchemy" import space. * Column(ForeignKey()) no longer needs to be `@declared_attr` if the FK refers to a remote table * composite() attributes mapped to a dataclass no longer need to implement a `__composite_values__()` method * with_variant() accepts multiple dialect names Change-Id: I22797c0be73a8fbbd2d6f5e0c0b7258b17fe145d Fixes: #7535 Fixes: #7551 References: #6810
* initial reorganize for static typingMike Bayer2022-01-121-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | start applying foundational annotations to key elements. two main elements addressed here: 1. removal of public_factory() and replacement with explicit functions. this just works much better with typing. 2. typing support for column expressions and operators. The biggest part of this involves stubbing out all the ColumnOperators methods under ColumnElement in a TYPE_CHECKING section. Took me a while to see this method vs. much more complicated things I thought I needed. Also for this version implementing #7519, ColumnElement types against the Python type and not TypeEngine. it is hoped this leads to easier transferrence between ORM/Core as well as eventual support for result set typing. Not clear yet how well this approach will work and what new issues it may introduce. given the current approach we now get full, rich typing for scenarios like this: from sqlalchemy import column, Integer, String, Boolean c1 = column('a', String) c2 = column('a', Integer) expr1 = c2.in_([1, 2, 3]) expr2 = c2 / 5 expr3 = -c2 expr4_a = ~(c2 == 5) expr4_b = ~column('q', Boolean) expr5 = c1 + 'x' expr6 = c2 + 10 Fixes: #7519 Fixes: #6810 Change-Id: I078d9f57955549f6f7868314287175f6c61c44cb
* happy new year 2022Mike Bayer2022-01-061-1/+1
| | | | Change-Id: I49abf2607e0eb0623650efdf0091b1fb3db737ea
* Update Black's target-version to py37Hugo van Kemenade2022-01-051-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | <!-- Provide a general summary of your proposed changes in the Title field above --> ### Description <!-- Describe your changes in detail --> Black's `target-version` was still set to `['py27', 'py36']`. Set it to `[py37]` instead. Also update Black and other pre-commit hooks and re-format with Black. ### 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 - [ ] 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: #7536 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/7536 Pull-request-sha: b3aedf5570d7e0ba6c354e5989835260d0591b08 Change-Id: I8be85636fd2c9449b07a8626050c8bd35bd119d5
* Remove object in class definitionFederico Caselli2021-11-221-3/+3
| | | | | References: #4600 Change-Id: I2a62ddfe00bc562720f0eae700a497495d7a987a
* Replace all http:// links to https://Federico Caselli2021-07-041-1/+1
| | | | | | Also replace http://pypi.python.org/pypi with https://pypi.org/project Change-Id: I84b5005c39969a82140706472989f2a30b0c7685
* ensure relationship.order_by stored as a tuple; check in dynamic alsoMike Bayer2021-05-271-1/+3
| | | | | | | | | | | Fixed regression in dynamic loader strategy and :func:`_orm.relationship` overall where the :paramref:`_orm.relationship.order_by` parameter were stored as a mutable list, which could then be mutated when combined with additional "order_by" methods used against the dynamic query object, causing the ORDER BY criteria to continue to grow repetitively. Fixes: #6549 Change-Id: I9f4c9a723aa0923f115cbe39bfaaa9cac62153b1
* Restore detached object logic for dynamic, but warnMike Bayer2021-05-041-5/+17
| | | | | | | | | | | | Fixed regression involving ``lazy='dynamic'`` loader in conjunction with a detached object. The previous behavior was that the dynamic loader upon calling methods like ``.all()`` returns empty lists for detached objects without error, this has been restored; however a warning is now emitted as this is not the correct result. Other dynamic loader scenarios correctly raise ``DetachedInstanceError``. Fixes: #6426 Change-Id: Id7ad204bef947491fa7e462c5acda2055fada910
* loader strategy regression fixesMike Bayer2021-05-031-2/+24
| | | | | | | | | | | | | | Fixed regression where using :func:`_orm.selectinload` and :func:`_orm.subqueryload` to load a two-level-deep path would lead to an attribute error. Fixed regression where using the :func:`_orm.noload` loader strategy in conjunction with a "dynamic" relationship would lead to an attribute error as the noload strategy would attempt to apply itself to the dynamic loader. Fixes: #6419 Fixes: #6420 Change-Id: I933b208f16a9723f6ebeab7addbe118903a1f8f5
* Revert AppenderQuery modifications from ORMMike Bayer2021-02-251-253/+60
| | | | | | | | | | | | | | We are unfortunately stuck with this class completely until we get rid of "dynamic" altogether. The usage contract includes the "query_class" mixin feature where users add their own methods, and this use case very well in line with 2.0's contract. As Query is not going away in any case this has to stay in "legacy" style, there's no point trying to change it as the new version was still fully dependent on Query. Fixes: #5981 Change-Id: I1bc623b17d976b4bb417ab623248d4ac227db74d
* happy new yearMike Bayer2021-01-041-1/+1
| | | | Change-Id: Ic5bb19ca8be3cb47c95a0d3315d84cb484bac47c
* upgrade to black 20.8b1Mike Bayer2020-09-281-2/+5
| | | | | | | It's better, the majority of these changes look more readable to me. also found some docstrings that had formatting / quoting issues. Change-Id: I582a45fde3a5648b2f36bab96bad56881321899b
* Deprecate negative slice indexesMike Bayer2020-09-221-1/+3
| | | | | | | | | | | | The "slice index" feature used by :class:`_orm.Query` as well as by the dynamic relationship loader will no longer accept negative indexes in SQLAlchemy 2.0. These operations do not work efficiently and load the entire collection in, which is both surprising and undesirable. These will warn in 1.4 unless the :paramref:`_orm.Session.future` flag is set in which case they will raise IndexError. Fixes: #5606 Change-Id: I5f5dcf984a8f41ab3d0e233ef7553e77fd99a771
* restore slice methods to dynamic queryMike Bayer2020-09-211-1/+12
| | | | | | | in f0f08db5715e41cc08e57dbc76a85300b these got lost, put them back and test Change-Id: Id1962e1f5d6160fe222becec5a8e32ec6a40017a
* See if the future is hereMike Bayer2020-08-281-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The docs are going to talk a lot about session.execute(select()) for ORM queries, and additionally it's much easier to help users with queries and such if we can use this new syntax. I'm hoping to see how hard it is to get a unified tutorial started that switches to new syntax. Basically, new syntax is much easier to explain and less buggy. But, if we are starting to present new syntax with the explicit goal of being easier to explain for less experienced programmers, the "future" thing is going to just be an impediment to that. See if we can remove "future" from session.execute(), so that ORM-enabled select() statements return ORM results at that level. This does not change the presence of the "future" flag for the Session's construction and for its transactional behaviors. The only perceptible change of the future flag for session.execute() is that session.execute(select()) where the statement has ORM entities in it now returns ORM new style tuples rather than old style tuples. Like mutating a URL, it's hopefully not very common that people are doing this. Change-Id: I0aa10322bb787d554d32772e3bc60548f1bf6206
* Convert remaining ORM APIs to support 2.0 styleMike Bayer2020-07-111-68/+236
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is kind of a mixed bag of all kinds to help get us to 1.4 betas. The documentation stuff is a work in progress. Lots of other relatively small changes to APIs and things. More commits will follow to continue improving the documentation and transitioning to the 1.4/2.0 hybrid documentation. In particular some refinements to Session usage models so that it can match Engine's scoping / transactional patterns, and a decision to start moving away from "subtransactions" completely. * add select().from_statement() to produce FromStatement in an ORM context * begin referring to select() that has "plugins" for the few edge cases where select() will have ORM-only behaviors * convert dynamic.AppenderQuery to its own object that can use select(), though at the moment it uses Query to support legacy join calling forms. * custom query classes for AppenderQuery are replaced by do_orm_execute() hooks for custom actions, a separate gerrit will document this * add Session.get() to replace query.get() * Deprecate session.begin->subtransaction. propose within the test suite a hypothetical recipe for apps that rely on this pattern * introduce Session construction level context manager, sessionmaker context manager, rewrite the whole top of the session_transaction.rst documentation. Establish context manager patterns for Session that are identical to engine * ensure same begin_nested() / commit() behavior as engine * devise all new "join into an external transaction" recipe, add test support for it, add rules into Session so it just works, write new docs. need to ensure this doesn't break anything * vastly reduce the verbosity of lots of session docs as I dont think people read this stuff and it's difficult to keep current in any case * constructs like case(), with_only_columns() really need to move to *columns, add a coercion rule to just change these. * docs need changes everywhere I look. in_() is not in the Core tutorial? how do people even know about it? Remove tons of cruft from Select docs, etc. * build a system for common ORM options like populate_existing and autoflush to populate from execution options. * others? Change-Id: Ia4bea0f804250e54d90b3884cf8aab8b66b82ecf
* Fix a wide variety of typos and broken linksaplatkouski2020-06-251-1/+1
| | | | | | | | | | | | Note the PR has a few remaining doc linking issues listed in the comment that must be addressed separately. Signed-off-by: aplatkouski <5857672+aplatkouski@users.noreply.github.com> Closes: #5371 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/5371 Pull-request-sha: 7e7d233cf3a0c66980c27db0fcdb3c7d93bc2510 Change-Id: I9c36e8d8804483950db4b42c38ee456e384c59e3
* Unify Query and select() , move all processing to compile phaseMike Bayer2020-05-241-4/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | Convert Query to do virtually all compile state computation in the _compile_context() phase, and organize it all such that a plain select() construct may also be used as the source of information in order to generate ORM query state. This makes it such that Query is not needed except for its additional methods like from_self() which are all to be deprecated. The construction of ORM state will occur beyond the caching boundary when the new execution model is integrated. future select() gains a working join() and filter_by() method. as we continue to rebase and merge each commit in the steps, callcounts continue to bump around. will have to look at the final result when it's all in. References: #5159 References: #4705 References: #4639 References: #4871 References: #5010 Change-Id: I19e05b3424b07114cce6c439b05198ac47f7ac10
* Simplified module pre-loading strategy and made it linter friendlyFederico Caselli2020-03-071-2/+2
| | | | | | | | | | | | | | | | | Introduced a modules registry to register modules that should be lazily loaded in the package init. This ensures that they are in the system module cache, avoiding potential thread safety issues as when importing them directly in the function that uses them. The module registry is used to obtain these modules directly, ensuring that the all the lazily loaded modules are resolved at the proper time This replaces dependency_for decorator and the dependencies decorator logic, removing the need to pass the resolved modules as arguments of the decodated functions and removes possible errors caused by linters. Fixes: #4689 Fixes: #4656 Change-Id: I2e291eba4297867fc0ddb5d875b9f7af34751d01
* happy new yearMike Bayer2020-01-011-1/+1
| | | | Change-Id: I08440dc25e40ea1ccea1778f6ee9e28a00808235
* Unify generation between Core and ORM queryMike Bayer2019-09-261-4/+4
| | | | | | | | | | | | | | generation is to be enhanced to include caching functionality, so ensure that Query and all generative in Core (e.g. select, DML etc) are using the same generations system. Additionally, deprecate Select.append methods and state Select methods independently of their append versions. Mutability of expression objects is a special case only when generating new objects during a visit. Fixes: #4637 Change-Id: I3dfac00d5e0f710c833b236f7a0913e1ca24dde4
* Fixes for uselist=True with m2o relationshipsMike Bayer2019-07-181-0/+12
| | | | | | | | | | | | | | | Fixed bug where a many-to-one relationship that specified ``uselist=True`` would fail to update correctly during a primary key change where a related column needs to change. Fixed bug where the detection for many-to-one or one-to-one use with a "dynamic" relationship, which is an invalid configuration, would fail to raise if the relationship were configured with ``uselist=True``. The current fix is that it warns, instead of raises, as this would otherwise be backwards incompatible, however in a future release it will be a raise. Fixes: #4772 Change-Id: Ibd5d2f7329ff245c88118e2533fc8ef42a09fef3
* happy new yearMike Bayer2019-01-111-1/+1
| | | | Change-Id: I6a71f4924d046cf306961c58dffccf21e9c03911
* Post black reformattingMike Bayer2019-01-061-11/+10
| | | | | | | | | | | | | Applied on top of a pure run of black -l 79 in I7eda77fed3d8e73df84b3651fd6cfcfe858d4dc9, this set of changes resolves all remaining flake8 conditions for those codes we have enabled in setup.cfg. Included are resolutions for all remaining flake8 issues including shadowed builtins, long lines, import order, unused imports, duplicate imports, and docstring issues. Change-Id: I4f72d3ba1380dd601610ff80b8fb06a2aff8b0fe
* Run black -l 79 against all source filesMike Bayer2019-01-061-74/+134
| | | | | | | | | | | | | | This is a straight reformat run using black as is, with no edits applied at all. The black run will format code consistently, however in some cases that are prevalent in SQLAlchemy code it produces too-long lines. The too-long lines will be resolved in the following commit that will resolve all remaining flake8 issues including shadowed builtins, long lines, import order, unused imports, duplicate imports, and docstring issues. Change-Id: I7eda77fed3d8e73df84b3651fd6cfcfe858d4dc9
* Insert primary entity in dynamic "secondary"Mike Bayer2018-11-131-1/+7
| | | | | | | | | | | | Fixed regression caused by :ticket:`4349` where adding the "secondary" table to the FROM clause for a dynamic loader would affect the ability of the :class:`.Query` to make a subsequent join to another entity. The fix adds the primary entity as the first element of the FROM list since :meth:`.Query.join` wants to jump from that. Version 1.3 will have a more comprehensive solution to this problem as well (:ticket:`4365`). Fixes: #4363 Change-Id: I1abbb6207722619dc5369e1fd96de43d60a1ee62
* Add prop.secondary to FROM for dynamic loaderMike Bayer2018-10-171-0/+5
| | | | | | | | | | Fixed bug where "dynamic" loader needs to explicitly set the "secondary" table in the FROM clause of the query, to suit the case where the secondary is a join object that is otherwise not pulled into the query from its columns alone. Fixes: #4349 Change-Id: I397f62abd5603efa4fb273586d0f772bf8c8fbbf
* Ensure backrefs accommodate for op_bulk_replaceMike Bayer2018-01-241-0/+1
| | | | | | | | | | | | | | | Fixed 1.2 regression regarding new bulk_replace event where a backref would fail to remove an object from the previous owner when a bulk-assignment assigned the object to a new owner. As this revisits the Event tokens associated with AttributeImpl objects, remove the verbosity of the "inline lazy init" pattern; the Event token is a simple slotted object and should have minimal memory overhead. Change-Id: Id188b4026fc2f3500186548008f4db8cdf7afecc Fixes: #4171
* happy new yearMike Bayer2018-01-121-1/+1
| | | | Change-Id: I3ef36bfd0cb0ba62b3123c8cf92370a43156cf8f
* Support state expiration for with_expression(); rename deferred_expressionMike Bayer2017-06-261-1/+1
| | | | | | | | | | | | | | | The attributeimpl for a deferred_expression does not support a scalar loader, add new configurability so that the impl can have this flag turned off. Document that the with_expression() system currently does not offer any deferred loading. To eliminate confusion over "deferred", which refers to lazy loading of column attributes, and "with_expression", which refers to an attribute that is explicitly at query time only, rename deferred_expression to query_expression. Change-Id: I07c4a050ed68c79ccbde9492e9de1630b7470d74
* update for 2017 copyrightMike Bayer2017-01-041-1/+1
| | | | Change-Id: I4e8c2aa8fe817bb2af8707410fa0201f938781de
* Move setup functionality into _register_attributeMike Bayer2016-11-061-3/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | Options like uselist and backref can be determined from within _register_attribute based on parent_property given; move this logic inside so that individual strategies have less responsibility. Also don't require that _register_attribute consider the "strategy" itself at all; it would be better if we could no longer require that Joined/Subquery/etc loaders call upon the "lazy" strategy in order to initialize attribute instrumentation and this could be done more generically. Fixes long-standing bug where the "noload" relationship loading strategy would cause backrefs and/or back_populates options to be ignored. There is concern that some application that uses "noload" might be surprised at a back-populating attribute appearing suddenly, which may have side effects. However, "noload" itself must be extremely seldom used since as a strategy, it already disables loading, population of attributes is the only behavior that is even supported, so that this issue has existed for at least through 0.7 four years ago without ever being reported indicates extremely low use of this option. Change-Id: Icffb9c83ac5782b76ce882ed1df4361a1efbfba3 Fixes: #3845
* - happy new yearMike Bayer2016-01-291-1/+1
|
* - refactor of adapt_like_to_iterable(), fixes #3457.Mike Bayer2015-12-091-4/+3
| | | | | | Includes removal of adapt_like_to_iterable() as well as _set_iterable(), uses __slots__ for collectionadapter, does much less duck typing of collections.
* - copyright 2015Mike Bayer2015-03-101-1/+1
|
* - remove some old cruftMike Bayer2014-09-071-3/+1
| | | | | | - prop.compare() isn't needed; replace with prop._with_parent() for relationships - update docs in orm/interfaces
* - apply pep8 formatting to sqlalchemy/sql, sqlalchemy/util, sqlalchemy/dialects,Brian Jarrett2014-07-201-39/+41
| | | | sqlalchemy/orm, sqlalchemy/event, sqlalchemy/testing
* - break up the <authors> copyright comment as part of a passMike Bayer2014-07-091-1/+2
| | | | to get all flake8 passing
* - Fixed bug involving dynamic attributes, that was again a regressionMike Bayer2014-06-261-2/+3
| | | | | | of :ticket:`3060` from verision 0.9.5. A self-referential relationship with lazy='dynamic' would raise a TypeError within a flush operation. fixes #3099
* - happy new yearMike Bayer2014-01-051-1/+1
|