summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/orm/interfaces.py
Commit message (Collapse)AuthorAgeFilesLines
* happy new year 2023Mike Bayer2023-01-031-1/+1
| | | | Change-Id: I625af65b3fb1815b1af17dc2ef47dd697fdc3fb1
* Merge "add new pattern for single inh column override" into mainmike bayer2022-12-011-0/+2
|\
| * add new pattern for single inh column overrideMike Bayer2022-11-301-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Added a new parameter :paramref:`_orm.mapped_column.use_existing_column` to accommodate the use case of a single-table inheritance mapping that uses the pattern of more than one subclass indicating the same column to take place on the superclass. This pattern was previously possible by using :func:`_orm.declared_attr` in conjunction with locating the existing column in the ``.__table__`` of the superclass, however is now updated to work with :func:`_orm.mapped_column` as well as with pep-484 typing, in a simple and succinct way. Fixes: #8822 Change-Id: I2296a4a775da976c642c86567852cdc792610eaf
* | Add "compare" on dataclass fieldsSimon Schiele2022-11-301-1/+9
|/ | | | | | | | | | | | | | | | | | | Added :paramref:`_orm.mapped_column.compare` parameter to relevant ORM attribute constructs including :func:`_orm.mapped_column`, :func:`_orm.relationship` etc. to provide for the Python dataclasses ``compare`` parameter on ``field()``, when using the :ref:`orm_declarative_native_dataclasses` feature. Pull request courtesy Simon Schiele. Added an additional case for associationproxy into test_dc_transforms.py -> test_attribute_options Fixes: #8905 Closes: #8906 Pull-request: https://github.com/sqlalchemy/sqlalchemy/pull/8906 Pull-request-sha: ea9a53d2ca60befdd0c570013c0e57a78c11dd4a Change-Id: I390d043b06c1d668242325ef86e2f7b7dbfac442
* annotated / DC forms for association proxyMike Bayer2022-11-291-13/+25
| | | | | | | | | | | | | | | | | | | | | | | | Added support for the :func:`.association_proxy` extension function to take part within Python ``dataclasses`` configuration, when using the native dataclasses feature described at :ref:`orm_declarative_native_dataclasses`. Included are attribute-level arguments including :paramref:`.association_proxy.init` and :paramref:`.association_proxy.default_factory`. Documentation for association proxy has also been updated to use "Annotated Declarative Table" forms within examples, including type annotations used for :class:`.AssocationProxy` itself. Also modernized documentation examples in sqlalchemy.ext.mutable, which was not up to date even for 1.4 style code. Corrected typing for relationship(secondary) where "secondary" accepts a callable (i.e. lambda) as well Fixes: #8878 Fixes: #8876 Fixes: #8880 Change-Id: Ibd4f3591155a89f915713393e103e61cc072ed57
* add common base class for all SQL col expression objectsMike Bayer2022-11-211-2/+3
| | | | | | | | | | | 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
* evaluate types in terms of the class in which they appearMike Bayer2022-10-311-2/+4
| | | | | | | | | | | Fixed issues within the declarative typing resolver (i.e. which resolves ``ForwardRef`` objects) where types that were declared for columns in one particular source file would raise ``NameError`` when the ultimate mapped class were in another source file. The types are now resolved in terms of the module for each class in which the types are used. Fixes: #8742 Change-Id: I236f94484ea79d47392a6201e671eeb89c305fd8
* ensure inherited mapper attrs not interpreted as plain dataclass fieldsMike Bayer2022-10-261-1/+19
| | | | | | | | | Fixed issue in new dataclass mapping feature where a column declared on the decalrative base / abstract base / mixin would leak into the constructor for an inheriting subclass under some circumstances. Fixes: #8718 Change-Id: Ic519acf239e2f80541516f10995991cbbbed00bd
* implement write-only colletions, typing for dynamicMike Bayer2022-10-061-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | 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
* New ORM Query Guide featuring DML supportMike Bayer2022-09-251-2/+3
| | | | | | | | | | | | | | | | | 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
* Merge "validate mapped collection key is loaded" into mainmike bayer2022-08-171-0/+1
|\
| * validate mapped collection key is loadedMike Bayer2022-08-171-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Changed the attribute access method used by :func:`_orm.attribute_mapped_collection` and :func:`_orm.column_mapped_collection`, used when populating the dictionary, to assert that the data value on the object to be used as the dictionary key is actually present, and is not instead using "None" due to the attribute never being actually assigned. This is used to prevent a mis-population of None for a key when assigning via a backref where the "key" attribute on the object is not yet assigned. As the failure mode here is a transitory condition that is not typically persisted to the database, and is easy to produce via the constructor of the class based on the order in which parameters are assigned, it is very possible that many applications include this behavior already which is silently passed over. To accommodate for applications where this error is now raised, a new parameter :paramref:`_orm.attribute_mapped_collection.ignore_unpopulated_attribute` is also added to both :func:`_orm.attribute_mapped_collection` and :func:`_orm.column_mapped_collection` that instead causes the erroneous backref assignment to be skipped. Fixes: #8372 Change-Id: I85bf4af405adfefe6386f0f2f8cef22537d95912
* | Merge "refine transfer of cached ORM options for selectin, lazy" into mainmike bayer2022-08-171-0/+45
|\ \ | |/ |/|
| * refine transfer of cached ORM options for selectin, lazyMike Bayer2022-08-171-0/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixed issue involving :func:`_orm.with_loader_criteria` where a closure variable used as bound parameter value within the lambda would not carry forward correctly into additional relationship loaders such as :func:`_orm.selectinload` and :func:`_orm.lazyload` after the statement were cached, using the stale originally-cached value instead. This change brings forth a good refinement where we finally realize we shouldn't be testing every ORM option with lots of switches, we just let the option itself be given "here is your uncached version, you are cached, tell us what to do!". the current decision is that strategy loader options used the cached in all cases as they always have, with_loader_criteria uses the uncached, because the uncached will have been invoked with new closure state that we definitely need. The only edge that might not work is if with_loader_criteria referenced an entity that is local to the query, namely a specific AliasedInsp, however that's not a documented case for this. if we had to do that, then we perhaps would introduce a more complex reconcilation logic, and this would also give us the hook to do that. Fixes: #8399 Change-Id: Ided8e2123915131e3f11cf6b06d773039e73797a
* | Propagate key for collection eventsMike Bayer2022-08-161-0/+1
|/ | | | | | | | | | | | | | | Added new parameter :paramref:`_orm.AttributeEvents.include_key`, which will include the dictionary or list key for operations such as ``__setitem__()`` (e.g. ``obj[key] = value``) and ``__delitem__()`` (e.g. ``del obj[key]``), using a new keyword parameter "key" or "keys", depending on event, e.g. :paramref:`_orm.AttributeEvents.append.key`, :paramref:`_orm.AttributeEvents.bulk_replace.keys`. This allows event handlers to take into account the key that was passed to the operation and is of particular importance for dictionary operations working with :class:`_orm.MappedCollection`. Fixes: #8375 Change-Id: Icc472f7c28848f94e15c94a399cc13a88782e1e4
* doc fixesMike Bayer2022-08-101-0/+21
| | | | | | | | | | | | | | | | | * 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
* Support kw_only and match_args in dataclass mappingFederico Caselli2022-08-041-1/+4
| | | | | Fixes: #8346 Change-Id: I964629e3bd25221bf6df6ab31c59b3ce1983cd9a
* new features for pep 593 AnnotatedMike Bayer2022-06-151-0/+9
| | | | | | | | | | | | | | | * extract the inner type from Annotated when the outer type isn't present in the type map, to allow for arbitrary Annotated * allow _IntrospectsAnnotations objects to be directly present in an Annotated and resolve the mapper property from that. Currently implemented for mapped_column(), with message for others. Can work for composite() and likely some relationship() as well at some point References: https://twitter.com/zzzeek/status/1536693554621341697 and replies Change-Id: I04657050a8785f194bf8f63291faf3475af88781
* implement dataclass_transformsMike Bayer2022-05-201-1/+96
| | | | | | | | | | | | | | | | | | | | | | | | Implement a new means of creating a mapped dataclass where instead of applying the `@dataclass` decorator distinctly, the declarative process itself can create the dataclass. MapperProperty and MappedColumn objects themselves take the place of the dataclasses.Field object when constructing the class. The overall approach is made possible at the typing level using pep-681 dataclass transforms [1]. This new approach should be able to completely supersede the previous "dataclasses" approach of embedding metadata into Field() objects, which remains a mutually exclusive declarative setup style (mixing them introduces new issues that are not worth solving). [1] https://peps.python.org/pep-0681/#transform-descriptor-types-example Fixes: #7642 Change-Id: I6ba88a87c5df38270317b4faf085904d91c8a63c
* revenge of pep 484Mike Bayer2022-05-151-47/+68
| | | | | | trying to get remaining must-haves for ORM Change-Id: I66a3ecbbb8e5ba37c818c8a92737b576ecf012f7
* update for flake8-future-imports 0.0.5Mike Bayer2022-05-141-9/+8
| | | | | | | | a whole bunch of errors were apparently blocked by 0.0.4 being installed. Fixes: #8020 Change-Id: I22a0faeaabe03de501897893391946d677c2df7e
* pep484: attributes and relatedMike Bayer2022-05-031-21/+24
| | | | | | | 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/+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-98/+204
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* pep484: schema APIMike Bayer2022-04-151-2/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* pep-484: session, instancestate, etcMike Bayer2022-04-121-0/+6
| | | | | | | | 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
* pep-484: the pep-484ening, SQL part threeMike Bayer2022-03-301-4/+6
| | | | | | | | | | | | | | | 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
* pep484 for hybridMike Bayer2022-03-171-1/+3
| | | | | Change-Id: I53274b13094d996e11b04acb03f9613edbddf87f References: #6810
* pep-484 - SQL column operationsMike Bayer2022-03-151-4/+2
| | | | | | | | | note we are taking out the ColumnOperartors[SQLCoreOperations] thing; not really clear why that was needed and at the moment it seems I was likely confused. Change-Id: I834b75f9b44f91b97e29f2e1a7b1029bd910e0a1
* pep484 + abc bases for assocaitionproxyMike Bayer2022-03-011-34/+34
| | | | | | | | | | 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
* establish mypy / typing approach for v2.0Mike Bayer2022-02-131-13/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Add new infrastructure to support greater use of __slots__Mike Bayer2022-01-211-0/+14
| | | | | | | | | | | | | | | | | | | * Changed AliasedInsp to use __slots__ * Migrated all of strategy_options to use __slots__ for objects. Adds new infrastructure to traversals to support shallow copy, to dict and from dict based on internal traversal attributes. Load / _LoadElement then leverage this to provide clone / generative / getstate without the need for __dict__ or explicit attribute lists. Doing this change revealed that there are lots of things that trigger off of whether or not a class has a __visit_name__ attribute. so to suit that we've gone back to having Visitable, which is a better name than Traversible at this point (I think Traversible is mis-spelled too). Change-Id: I13d04e494339fac9dbda0b8e78153418abebaf72 References: #7527
* Initial ORM typing layoutMike Bayer2022-01-141-17/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | introduces: 1. new mapped_column() helper 2. DeclarativeBase helper 3. declared_attr has been re-typed 4. rework of Mapped[] to return InstrumentedAtribute for class get, so works without Mapped itself having expression methods 5. ORM constructs now generic on [_T] also includes some early typing work, most of which will be in later commits: 1. URL and History become typing.NamedTuple 2. come up with type-checking friendly way of type checking cy extensions, where type checking will be applied to the py versions, just needed to come up with a succinct conditional pattern for the imports References: #6810 References: #7535 References: #7562 Change-Id: Ie5d9a44631626c021d130ca4ce395aba623c71fb
* initial reorganize for static typingMike Bayer2022-01-121-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* remove internal use of metaclassesMike Bayer2022-01-111-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | All but one metaclass used internally can now be replaced using __init_subclass__(). Within this patch we remove: * events._EventMeta * sql.visitors.TraversibleType * sql.visitors.InternalTraversibleType * testing.fixtures.FindFixture * testing.fixtures.FindFixtureDeclarative * langhelpers.EnsureKWArgType * sql.functions._GenericMeta * sql.type_api.VisitableCheckKWArg (was a mixture of TraversibleType and EnsureKWArgType) The remaining internal class is MetaOptions used by the sql.Options object which is in turn currently mostly for ORM internal use, as this type implements class level overrides for the ``+`` operator. For declarative, removing DeclarativeMeta in place of an `__init_subclass__()` class would not be fully feasible as it would break backwards compatibility with applications that refer to this class explicitly, but also DeclarativeMeta intercepts class-level attribute set and delete operations which is a widely used pattern. An option for declarative base to use `__init_subclass__()` should be provided but this is out of scope for this particular change. Change-Id: I8aa898c7ab59d887739037d34b1cbab36521ab78 References: #6810
* happy new year 2022Mike Bayer2022-01-061-1/+1
| | | | Change-Id: I49abf2607e0eb0623650efdf0091b1fb3db737ea
* factor out UnboundLoad and rearchitect strategy_options.pyMike Bayer2021-12-271-20/+20
| | | | | | | | | | | | | | | | | | | | | The architecture of Load is mostly rewritten here. The change includes removal of the "pluggable" aspect of the loader options, which would patch new methods onto Load. This has been replaced by normal methods that respond normally to typing annotations. As part of this change, the bake_loaders() and unbake_loaders() options, which have no effect since 1.4 and were unlikely to be in any common use, have been removed. Additionally, to support annotations for methods that make use of @decorator, @generative etc., modified format_argspec_plus to no longer return "args", instead returns "grouped_args" which is always grouped and allows return annotations to format correctly. Fixes: #6986 Change-Id: I6117c642345cdde65a64389bba6057ddd5374427
* Warn when caching is disabled / documentMike Bayer2021-12-061-5/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds new warnings for all elements that don't indicate their caching behavior, including user-defined ClauseElement subclasses and third party dialects. it additionally adds new documentation to discuss an apparent performance degradation in 1.4 when caching is disabled as a result in the significant expense incurred by ORM lazy loaders, which in 1.3 used BakedQuery so were actually cached. As a result of adding the warnings, a fair degree of lesser used SQL expression objects identified that they did not define caching behavior so would have been producing ``[no key]``, including PostgreSQL constructs ``hstore`` and ``array``. These have been amended to use inherit cache where appropriate. "on conflict" constructs in PostgreSQL, MySQL, SQLite still explicitly don't generate a cache key at this time. The change also adds a test for all constructs via assert_compile() to assert they will not generate cache warnings. Fixes: #7394 Change-Id: I85958affbb99bfad0f5efa21bc8f2a95e7e46981
* Clean up most py3k compatFederico Caselli2021-11-241-2/+0
| | | | Change-Id: I8172fdcc3103ff92aa049827728484c8779af6b7
* Remove object in class definitionFederico Caselli2021-11-221-1/+1
| | | | | References: #4600 Change-Id: I2a62ddfe00bc562720f0eae700a497495d7a987a
* consider "inspect(_of_type)" to be the entity of a comparatorMike Bayer2021-10-271-1/+4
| | | | | | | | | | | Fixed 1.4 regression where :meth:`_orm.Query.filter_by` would not function correctly when :meth:`_orm.Query.join` were joined to an entity which made use of :meth:`_orm.PropComparator.of_type` to specify an aliased version of the target entity. The issue also applies to future style ORM queries constructed with :func:`_sql.select`. Fixes: #7244 Change-Id: Ied28a03ce93201f932c7172d283cd4297be4d592
* use correct entity in path for aliased class relationshipMike Bayer2021-10-221-0/+9
| | | | | | | | | | | | | | | | Fixed bug in "relationship to aliased class" feature introduced at :ref:`relationship_aliased_class` where it was not possible to create a loader strategy option targeting an attribute on the target using the :func:`_orm.aliased` construct directly in a second loader option, such as ``selectinload(A.aliased_bs).joinedload(aliased_b.cs)``, without explicitly qualifying using :meth:`_orm.PropComparator.of_type` on the preceding element of the path. Additionally, targeting the non-aliased class directly would be accepted (inappropriately), but would silently fail, such as ``selectinload(A.aliased_bs).joinedload(B.cs)``; this now raises an error referring to the typing mismatch. Fixes: #7224 Change-Id: I40857c7275667dcb64f1d1fd0c8072e48758e678
* rewrite _extra_criteria in selectinload; propagate correctly to LoadMike Bayer2021-08-171-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixed issue in :func:`_orm.selectinload` where use of the new :meth:`_orm.PropComparator.and_` feature within options that were nested more than one level deep would fail to update bound parameter values that were in the nested criteria, as a side effect of SQL statement caching. Implementation adds a new step that rewrites the parameters inside of all _extra_criteria when invoking selectinload as well as subqueryload. Additionally, changed how Load() gets "extra_criteria", in that it pulls it from UnboundLoad._extra_criteria instead of re-fetching it from the path elements, which are not updated by this new step. This patch also builds upon the removal of lambda queries for use in loader strategies in #6889. lambdas made this issue much more difficult to diagnose. An attempt to reintroduce lambdas here after finally identifying the "extra_criteria" issue above showed that lambdas still impact the assertsql fixture, meaning we have a statement structure that upon calling .compile() still delivers stale data due to lambdas, even if caching is turned off, and the non-cached test was still failing due to stale data within the lambdas. This is basically the complexity that #6889 fixes and as there's no real performance gain to using lambdas in these strategies on top of the existing statement caching that does most of the work, it should be much less likely going forward to have as many deeply confusing issues as we've had within selectinload/lazyload in the 1.4 series. Fixes: #6881 Change-Id: I919c079d2ed06125def5f8d6d81f3f305e158c04
* 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
* memoize current options and joins w with_entities/with_only_colsMike Bayer2021-06-171-0/+12
| | | | | | | | | | | | | | | | Fixed further regressions in the same area as that of :ticket:`6052` where loader options as well as invocations of methods like :meth:`_orm.Query.join` would fail if the left side of the statement for which the option/join depends upon were replaced by using the :meth:`_orm.Query.with_entities` method, or when using 2.0 style queries when using the :meth:`_sql.Select.with_only_columns` method. A new set of state has been added to the objects which tracks the "left" entities that the options / join were made against which is memoized when the lead entities are changed. Fixes: #6503 Fixes: #6253 Change-Id: I211b2af98b0b20d1263fb15dc513884dcc5de6a4
* Ensure propagate_attrs available on PropComparatorMike Bayer2021-05-291-0/+12
| | | | | | | | | | | | | | | | | Fixed regression caused by just-released performance fix mentioned in #6550 where a query.join() to a relationship could produce an AttributeError if the query were made against non-ORM structures only, a fairly unusual calling pattern. In this fix, since we are no longer going through the production of ``__clause_element__()`` for Cls.some_relationship, I assumed we just throw this object away completely but I missed the one little bit where we might be getting ``_propagate_attrs`` from it. So we implement ``_propagate_attrs`` on ``PropComparator`` as well, since this is easy to define. Fixes: #6558 Change-Id: If781bf844e7e3d3b0841aff1c3668e9d6af9f097
* Remove pep484 type comments from the codeFederico Caselli2021-05-161-14/+4
| | | | | | | | | | | | | Current effort is around the stub package, and having typing in two places makes thing worse, since the types here are usually outdated compared to the version in the stubs. Once v2 gets under way we can start consolidating the types here. Fixes: #6461 Change-Id: I7132a444bd7138123074bf5bc664b4bb119a85ce