summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/mapper.py
Commit message (Collapse)AuthorAgeFilesLines
* add deterministic imv returning ordering using sentinel columnsMike Bayer2023-04-211-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Remove old versionadded and versionchangedFederico Caselli2023-04-121-14/+0
| | | | | | | Removed versionadded and versionchanged for version prior to 1.2 since they are no longer useful. Change-Id: I5c53d1188bc5fec3ab4be39ef761650ed8fa6d3e
* include columns from superclasses that indicate "selectin"Mike Bayer2023-02-271-3/+73
| | | | | | | | | | | | | Added support for the :paramref:`_orm.Mapper.polymorphic_load` parameter to be applied to each mapper in an inheritance hierarchy more than one level deep, allowing columns to load for all classes in the hierarchy that indicate ``"selectin"`` using a single statement, rather than ignoring elements on those intermediary classes that nonetheless indicate they also would participate in ``"selectin"`` loading and were not part of the base-most SELECT statement. Fixes: #9373 Change-Id: If8dcba0f0191f6c2818ecd15870bccfdf5ce1112
* Fix docs for `case` expression to match new syntax (#9279)Abdulhaq Emhemmed2023-02-101-2/+2
| | | | | | | | | * Fix docs for `case` expression to match new syntax Previously (before v1.4), the `whens` arg (when `value` is *not* used) used to be a list of conditions (a 2 item-tuple of condition + value). From v1.4, these are passed as positional args and the old syntax is not supported anymore. * Fix long lines
* Merge "port history meta to 2.0" into mainmike bayer2023-02-061-18/+27
|\
| * port history meta to 2.0Mike Bayer2023-02-061-18/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | first change: Reworked the :ref:`examples_versioned_history` to work with version 2.0, while at the same time improving the overall working of this example to use newer APIs, including a newly added hook :meth:`_orm.MapperEvents.after_mapper_constructed`. second change: Added new event hook :meth:`_orm.MapperEvents.after_mapper_constructed`, which supplies an event hook to take place right as the :class:`_orm.Mapper` object has been fully constructed, but before the :meth:`_orm.registry.configure` call has been called. This allows code that can create additional mappings and table structures based on the initial configuration of a :class:`_orm.Mapper`, which also integrates within Declarative configuration. Previously, when using Declarative, where the :class:`_orm.Mapper` object is created within the class creation process, there was no documented means of running code at this point. The change is to immediately benefit custom mapping schemes such as that of the :ref:`examples_versioned_history` example, which generate additional mappers and tables in response to the creation of mapped classes. third change: The infrequently used :attr:`_orm.Mapper.iterate_properties` attribute and :meth:`_orm.Mapper.get_property` method, which are primarily used internally, no longer implicitly invoke the :meth:`_orm.registry.configure` process. Public access to these methods is extremely rare and the only benefit to having :meth:`_orm.registry.configure` would have been allowing "backref" properties be present in these collections. In order to support the new :meth:`_orm.MapperEvents.after_mapper_constructed` event, iteration and access to the internal :class:`_orm.MapperProperty` objects is now possible without triggering an implicit configure of the mapper itself. The more-public facing route to iteration of all mapper attributes, the :attr:`_orm.Mapper.attrs` collection and similar, will still implicitly invoke the :meth:`_orm.registry.configure` step thus making backref attributes available. In all cases, the :meth:`_orm.registry.configure` is always available to be called directly. fourth change: Fixed obscure ORM inheritance issue caused by :ticket:`8705` where some scenarios of inheriting mappers that indicated groups of columns from the local table and the inheriting table together under a :func:`_orm.column_property` would nonetheless warn that properties of the same name were being combined implicitly. Fixes: #9220 Fixes: #9232 Change-Id: Id335b8e8071c8ea509c057c389df9dcd2059437d
* | Merge "coerce elements in mapper.primary_key, process in __mapper_args__" ↵mike bayer2023-02-051-5/+50
|\ \ | |/ |/| | | into main
| * coerce elements in mapper.primary_key, process in __mapper_args__Mike Bayer2023-02-051-6/+51
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Repaired ORM Declarative mappings to allow for the :paramref:`_orm.Mapper.primary_key` parameter to be specified within ``__mapper_args__`` when using :func:`_orm.mapped_column`. Despite this usage being directly in the 2.0 documentation, the :class:`_orm.Mapper` was not accepting the :func:`_orm.mapped_column` construct in this context. Ths feature was already working for the :paramref:`_orm.Mapper.version_id_col` and :paramref:`_orm.Mapper.polymorphic_on` parameters. As part of this change, the ``__mapper_args__`` attribute may be specified without using :func:`_orm.declared_attr` on a non-mapped mixin class, including a ``"primary_key"`` entry that refers to :class:`_schema.Column` or :func:`_orm.mapped_column` objects locally present on the mixin; Declarative will also translate these columns into the correct ones for a particular mapped class. This again was working already for the :paramref:`_orm.Mapper.version_id_col` and :paramref:`_orm.Mapper.polymorphic_on` parameters. Additionally, elements within ``"primary_key"`` may be indicated as string names of existing mapped properties. Fixes: #9240 Change-Id: Ie2000273289fa23e0af21ef9c6feb3962a8b848c
* | dont add non-server-side cols to returning for versioningMike Bayer2023-02-031-1/+19
|/ | | | | | | | | | | Fixed regression where using the :paramref:`_orm.Mapper.version_id_col` feature with a regular Python-side incrementing column would fail to work for SQLite and other databases that don't support "rowcount" with "RETURNING", as "RETURNING" would be assumed for such columns even though that's not what actually takes place. Fixes: #9228 Change-Id: I6a1a7fa4d63e183fe4ef0fbfd3cb5cac03b26d78
* fix regression based on mis-match of set/frozensetMike Bayer2023-01-271-1/+5
| | | | | | | | | Fixed regression where ORM models that used joined table inheritance with a composite foreign key would encounter an internal error in the mapper internals. Fixes: #9164 Change-Id: I8fdcdf6d72f3304bee191498d5554555b0ab7855
* add context for warnings emitted from configure_mappers(), autoflush()jonathan vanasco2023-01-241-0/+6
| | | | | | | | | | | Improved the notification of warnings that are emitted within the configure mappers or flush process, which are often invoked as part of a different operation, to add additional context to the message that indicates one of these operations as the source of the warning within operations that may not be obviously related. Fixes: #7305 Change-Id: I79da7a6a5d4cf67d57615d0ffc2b8d8454011c84
* clarify __table__, local_tableMike Bayer2023-01-201-9/+9
| | | | | | | | These are typed as FromClause, make sure this is stated up front indicating Table as a subset of possible object types. Change-Id: I15961a69d3655600249e3cfe6c4b3372f97d4485 References: #9130
* implement polymorphic_abstract=True featureMike Bayer2023-01-141-20/+67
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Added a new parameter to :class:`_orm.Mapper` called :paramref:`_orm.Mapper.polymorphic_abstract`. The purpose of this directive is so that the ORM will not consider the class to be instantiated or loaded directly, only subclasses. The actual effect is that the :class:`_orm.Mapper` will prevent direct instantiation of instances of the class and will expect that the class does not have a distinct polymorphic identity configured. In practice, the class that is mapped with :paramref:`_orm.Mapper.polymorphic_abstract` can be used as the target of a :func:`_orm.relationship` as well as be used in queries; subclasses must of course include polymorphic identities in their mappings. The new parameter is automatically applied to classes that subclass the :class:`.AbstractConcreteBase` class, as this class is not intended to be instantiated. Additionally, updated some areas of the single table inheritance documentation to include mapped_column(nullable=False) for all subclass-only columns; the mappings as given didn't work as the columns were no longer nullable using Annotated Declarative Table style. Fixes: #9060 Change-Id: Ief0278e3945a33a6ff38ac14d39c38ce24910d7f
* accept TableClause through mapped selectable chainMike Bayer2023-01-091-16/+10
| | | | | | | | | | | | | | type annotation somehow decided that TableClause doesn't have primary key fields which is not the case at all. In particular the "views" recipe relies on TableClause so adding a restriction like this does not make any sense. It seems the issue was to open this up for typing, by allowing TableClause out as far as ddl.sort_tables() typing is passing for now. Support it out in get_bind() etc. Fixes: #9071 Change-Id: If0e22e0e7df7bee0ff4b295b0ffacfbc6b7a0142
* happy new year 2023Mike Bayer2023-01-031-1/+1
| | | | Change-Id: I625af65b3fb1815b1af17dc2ef47dd697fdc3fb1
* rename 2.0.0b5 to 2.0.0rc1Mike Bayer2022-12-271-1/+1
| | | | | | it's hoped for 2.0.0 final to be next, in early January Change-Id: If4285f0929f4a2895f2bc93d9e8336599b973bcf
* Merge "add eager_defaults="auto" for inserts" into mainmike bayer2022-12-161-9/+43
|\
| * add eager_defaults="auto" for insertsMike Bayer2022-12-151-9/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* | warn when backref will replace existing userland descriptorMike Bayer2022-12-141-2/+18
|/ | | | | | | | | | A warning is emitted if a backref name used in :func:`_orm.relationship` names an attribute on the target class which already has a method or attribute assigned to that name, as the backref declaration will replace that attribute. Fixes: #4629 Change-Id: I0059b35ce60f43b0f3d8be008f12411154484ea1
* disable polymorphic adaption in most casesMike Bayer2022-12-071-9/+41
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Improved a fix first made in version 1.4 for :ticket:`8456` which scaled back the usage of internal "polymorphic adapters", that are used to render ORM queries when the :paramref:`_orm.Mapper.with_polymorphic` parameter is used. These adapters, which are very complex and error prone, are now used only in those cases where an explicit user-supplied subquery is used for :paramref:`_orm.Mapper.with_polymorphic`, which includes only the use case of concrete inheritance mappings that use the :func:`_orm.polymorphic_union` helper, as well as the legacy use case of using an aliased subquery for joined inheritance mappings, which is not needed in modern use. For the most common case of joined inheritance mappings that use the built-in polymorphic loading scheme, which includes those which make use of the :paramref:`_orm.Mapper.polymorphic_load` parameter set to ``inline``, polymorphic adapters are now no longer used. This has both a positive performance impact on the construction of queries as well as a substantial simplification of the internal query rendering process. The specific issue targeted was to allow a :func:`_orm.column_property` to refer to joined-inheritance classes within a scalar subquery, which now works as intuitively as is feasible. ORM context, mapper, strategies now use ORMAdapter in all cases instead of straight ColumnAdapter; added some more parameters to ORMAdapter to make this possible. ORMAdapter now includes a "trace" enumeration that identifies the use path for the adapter and can aid in debugging. implement __slots__ for the ExternalTraversal hierarchy up to ORMAdapter. Within this change, we have to change the ClauseAdapter.wrap() method, which is only used in one polymorphic codepath, to use copy.copy() instead of `__dict__` access (apparently `__reduce_ex__` is implemented for objects with `__slots__`), and we also remove pickling ability, which should not be needed for adapters (this might have been needed for 1.3 and earlier in order for Query to be picklable, but none of that state is present within Query / select() / etc. anymore). Fixes: #8168 Change-Id: I3f6593eb02ab5e5964807c53a9fa4894c826d017
* Try running pyupgrade on the codeFederico Caselli2022-11-161-70/+49
| | | | | | | | 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
* resolve synonyms in dictionary form of Session.get()Mike Bayer2022-11-041-0/+18
| | | | | | | | | Improved "dictionary mode" for :meth:`_orm.Session.get` so that synonym names which refer to primary key attribute names may be indicated in the named dictionary. Fixes: #8753 Change-Id: I56112564a5c23b51b26e01c64087cbf4399cd951
* Merge "reconcile Mapper properties ordering against mapped Table" into mainmike bayer2022-10-251-73/+184
|\
| * reconcile Mapper properties ordering against mapped TableMike Bayer2022-10-251-73/+184
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* | skip ad-hoc properties within subclass_load_via_inMike Bayer2022-10-231-2/+11
|/ | | | | | | | | | Fixed issue where "selectin_polymorphic" loading for inheritance mappers would not function correctly if the :param:`_orm.Mapper.polymorphic_on` parameter referred to a SQL expression that was not directly mapped on the class. Fixes: #8704 Change-Id: I1b6be2650895fd18d2c804f6ba96de966d11041a
* warn for no polymorphic identity w/ poly hierarchyMike Bayer2022-10-111-3/+20
| | | | | | | | | | A warning is emitted when attempting to configure a mapped class within an inheritance hierarchy where the mapper is not given any polymorphic identity, however there is a polymorphic discriminator column assigned. Such classes should be abstract if they never intend to load directly. Fixes: #7545 Change-Id: I94f04e59736c73e3f39d883a75d763e3f06ecc3d
* reorganize Mapped[] super outside of MapperPropertyMike Bayer2022-10-051-9/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | 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
* add typing for sqlalchemy.orm.validatesMike Bayer2022-09-251-6/+8
| | | | | Fixes: #8577 Change-Id: Iede1c956078960fb866da45f1ac6aa43842516bc
* New ORM Query Guide featuring DML supportMike Bayer2022-09-251-11/+15
| | | | | | | | | | | | | | | | | 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-241-0/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * 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
* refine ruleset to determine when poly adaption should be usedMike Bayer2022-08-291-0/+35
| | | | | | | | | | | | | | Fixed regression appearing in the 1.4 series where a joined-inheritance query placed as a subquery within an enclosing query for that same entity would fail to render the JOIN correctly for the inner query. The issue manifested in two different ways prior and subsequent to version 1.4.18 (related issue #6595), in one case rendering JOIN twice, in the other losing the JOIN entirely. To resolve, the conditions under which "polymorphic loading" are applied have been scaled back to not be invoked for simple joined inheritance queries. Fixes: #8456 Change-Id: Ie4332fadb1dfc670cd31d098a6586a9f6976bcf7
* remove narrative "reconstructor" documentMike Bayer2022-08-191-2/+6
| | | | | | | this event hook is not commonly used and this page does not fit into the current narrative very well. We should possibly write a new paragraph regarding how instances load at some point though the best place to put it is not clear.
* doc fixesMike Bayer2022-08-101-18/+15
| | | | | | | | | | | | | | | | | * fixed erroneous use of mapped_column() in m2m relationship Table * Fill in full imports for some relationship examples that had partial imports; examples that have no imports, leave empty for now * converted joined/single inh mappings to annotated style * We have a problem with @declared_attr in that the error message is wrong if the mapped_column() returned doesnt have a type, and/or mapped_column() with @declared_attr doesnt use the annotation * fix thing where sphinx with undoc-members global setting seems to no longer tolerate ":attribute:" entries in autodoc classes, which is fine we can document the annotations now * Fix mapper params in inheritance to be on Mapper * add missing changelog file for instances remove Change-Id: I9b70b25a320d8122fade68bc4d1f82f8b72b26f3
* include column.default, column.onupdate in eager_defaultsMike Bayer2022-08-051-20/+52
| | | | | | | | | | | | | Fixed bug in the behavior of the :paramref:`_orm.Mapper.eager_defaults` parameter such that client-side SQL default or onupdate expressions in the table definition alone will trigger a fetch operation using RETURNING or SELECT when the ORM emits an INSERT or UPDATE for the row. Previously, only server side defaults established as part of table DDL and/or server-side onupdate expressions would trigger this fetch, even though client-side SQL expressions would be included when the fetch was rendered. Fixes: #7438 Change-Id: Iba719298ba4a26d185edec97ba77d2d54585e5a4
* update ORM declarative docs for new featuresMike Bayer2022-07-161-4/+8
| | | | | | | I screwed up a rebase or something so this was temporarily in Ic51a12de3358f3a451bd7cf3542b375569499fc1 Change-Id: I847ee1336381221c0112b67854df022edf596b25
* rework ORM mapping docsMike Bayer2022-06-211-4/+32
| | | | | | | | | | prepare docs for newly incoming mapper styles, including new dataclass mapping. move the existing dataclass/attrs docs all into their own section and try to improve organization and wording into the relatively recent "mapping styles" document. Change-Id: I0b5e2a5b6a70db65ab19b5bb0a2bb7df20e0b498
* remove "deannotate" from column_property expressionMike Bayer2022-05-291-4/+4
| | | | | | | | | | | | | | | | | | Fixed issue where using a :func:`_orm.column_property` construct containing a subquery against an already-mapped column attribute would not correctly apply ORM-compilation behaviors to the subquery, including that the "IN" expression added for a single-table inherits expression would fail to be included. This fix involves a few tweaks in the ORM adaptation logic, including a missing "parententity" adaptation on the mapper side. The specific mechanics here have a lot of moving parts so we will continue to add tests to assert these cases. In particular a more complete test for issue #2316 is added that was relying upon the deannotate happening here. Fixes: #8064 Change-Id: Ia85dd12dcf6e7c002b30de4a27d7aa66cb3cd20e
* revenge of pep 484Mike Bayer2022-05-151-26/+54
| | | | | | trying to get remaining must-haves for ORM Change-Id: I66a3ecbbb8e5ba37c818c8a92737b576ecf012f7
* update for flake8-future-imports 0.0.5Mike Bayer2022-05-141-1/+0
| | | | | | | | a whole bunch of errors were apparently blocked by 0.0.4 being installed. Fixes: #8020 Change-Id: I22a0faeaabe03de501897893391946d677c2df7e
* 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-7/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-232/+417
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* pep-484: asyncioMike Bayer2022-04-111-1/+3
| | | | | | | | | | | | | | | | | | | | | in this patch the asyncio/events.py module, which existed only to raise errors when trying to attach event listeners, is removed, as we were already coding an asyncio-specific workaround in upstream Pool / Session to raise this error, just moved the error out to the target and did the same thing for Engine. We also add an async_sessionmaker class. The initial rationale here is because sessionmaker() is hardcoded to Session subclasses, and there's not a way to get the use case of sessionmaker(class_=AsyncSession) to type correctly without changing the sessionmaker() symbol itself to be a function and not a class, which gets too complicated for what this is. Additionally, _SessionClassMethods has only three methods on it, one of which is not usable with asyncio (close_all()), the others not generally used from the session class. Change-Id: I064a5fa5d91cc8d5bbe9597437536e37b4e801fe
* pep-484: session, instancestate, etcMike Bayer2022-04-121-20/+56
| | | | | | | | Also adds some fixes to annotation-based mapping that have come up, as well as starts to add more pep-484 test cases Change-Id: Ia722bbbc7967a11b23b66c8084eb61df9d233fee
* repair ancient and incorrect commentMike Bayer2022-04-111-7/+3
| | | | | | | | | it referred towards _columntoproperty refering to lists of MapperProperty. this comment goes all the way to pre 0.1 being released. it's likely been wrong for nearly all that time. Change-Id: I71234ae58a6253249d92224356e38372e4aff148
* pep-484: the pep-484ening, SQL part threeMike Bayer2022-03-301-4/+5
| | | | | | | | | | | | | | | hitting DML which is causing us to open up the ColumnCollection structure a bit, as we do put anonymous column expressions with None here. However, we still want Table /TableClause to have named column collections that don't return None, so parametrize the "key" in this collection also. * rename some "immutable" elements to "readonly". we change the contents of immutablecolumncollection underneath, so it's not "immutable" Change-Id: I2593995a4e5c6eae874bed5bf76117198be8ae97
* trust user PK argument as given; don't reduceMike Bayer2022-03-231-9/+9
| | | | | | | | | | | | | | Fixed issue where the :class:`_orm.Mapper` would reduce a user-defined :paramref:`_orm.Mapper.primary_key` argument too aggressively, in the case of mapping to a ``UNION`` where for some of the SELECT entries, two columns are essentially equivalent, but in another, they are not, such as in a recursive CTE. The logic here has been changed to accept a given user-defined PK as given, where columns will be related to the mapped selectable but no longer "reduced" as this heuristic can't accommodate for all situations. Fixes: #7842 Change-Id: Ie46f0a3d42cae0501641fa213da0a9d5ca26c3ad
* support selectin_polymorphic w/ no fixed polymorphic_onMike Bayer2022-03-081-2/+9
| | | | | | | | | | | | | | | Fixed issue where the :func:`_orm.polymorphic_selectin` loader option would not work with joined inheritance mappers that don't have a fixed "polymorphic_on" column. Additionally added test support for a wider variety of usage patterns with this construct. Fixed bug where :func:`_orm.composite` attributes would not work in conjunction with the :func:`_orm.selectin_polymorphic` loader strategy for joined table inheritance. Fixes: #7799 Fixes: #7801 Change-Id: I7cfe32dfe844b188403b39545930c0aee71d0119
* pep484 + abc bases for assocaitionproxyMike Bayer2022-03-011-3/+9
| | | | | | | | | | went to this one next as it was going to be hard, and also exercises the ORM expression hierarchy a bit. made some adjustments to SQLCoreOperations etc. Change-Id: Ie5dde9218dc1318252826b766d3e70b17dd24ea7 References: #6810 References: #7774
* 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