@@ -126,6 +126,7 @@ def mapped_column(
126
126
insert_default : Optional [Any ] = _NoArg .NO_ARG ,
127
127
server_default : Optional [_ServerDefaultType ] = None ,
128
128
server_onupdate : Optional [FetchedValue ] = None ,
129
+ active_history : bool = False ,
129
130
quote : Optional [bool ] = None ,
130
131
system : bool = False ,
131
132
comment : Optional [str ] = None ,
@@ -258,6 +259,20 @@ def mapped_column(
258
259
259
260
.. versionadded:: 2.0.4
260
261
262
+ :param active_history=False:
263
+
264
+ When ``True``, indicates that the "previous" value for a
265
+ scalar attribute should be loaded when replaced, if not
266
+ already loaded. Normally, history tracking logic for
267
+ simple non-primary-key scalar values only needs to be
268
+ aware of the "new" value in order to perform a flush. This
269
+ flag is available for applications that make use of
270
+ :func:`.attributes.get_history` or :meth:`.Session.is_modified`
271
+ which also need to know the "previous" value of the attribute.
272
+
273
+ .. versionadded:: 2.0.10
274
+
275
+
261
276
:param init: Specific to :ref:`orm_declarative_native_dataclasses`,
262
277
specifies if the mapped attribute should be part of the ``__init__()``
263
278
method as generated by the dataclass process.
@@ -301,6 +316,7 @@ def mapped_column(
301
316
index = index ,
302
317
unique = unique ,
303
318
info = info ,
319
+ active_history = active_history ,
304
320
nullable = nullable ,
305
321
onupdate = onupdate ,
306
322
primary_key = primary_key ,
@@ -318,14 +334,27 @@ def mapped_column(
318
334
)
319
335
320
336
337
+ @util .deprecated_params (
338
+ ** {
339
+ arg : (
340
+ "2.0" ,
341
+ f"The :paramref:`_orm.column_property.{ arg } ` parameter is "
342
+ "deprecated for :func:`_orm.column_property`. This parameter "
343
+ "applies to a writeable-attribute in a Declarative Dataclasses "
344
+ "configuration only, and :func:`_orm.column_property` is treated "
345
+ "as a read-only attribute in this context." ,
346
+ )
347
+ for arg in ("init" , "kw_only" , "default" , "default_factory" )
348
+ }
349
+ )
321
350
def column_property (
322
351
column : _ORMColumnExprArgument [_T ],
323
352
* additional_columns : _ORMColumnExprArgument [Any ],
324
353
group : Optional [str ] = None ,
325
354
deferred : bool = False ,
326
355
raiseload : bool = False ,
327
356
comparator_factory : Optional [Type [PropComparator [_T ]]] = None ,
328
- init : Union [_NoArg , bool ] = _NoArg .NO_ARG ,
357
+ init : Union [_NoArg , bool ] = _NoArg .NO_ARG , # noqa: A002
329
358
repr : Union [_NoArg , bool ] = _NoArg .NO_ARG , # noqa: A002
330
359
default : Optional [Any ] = _NoArg .NO_ARG ,
331
360
default_factory : Union [_NoArg , Callable [[], _T ]] = _NoArg .NO_ARG ,
@@ -338,49 +367,58 @@ def column_property(
338
367
) -> MappedSQLExpression [_T ]:
339
368
r"""Provide a column-level property for use with a mapping.
340
369
341
- Column-based properties can normally be applied to the mapper's
342
- ``properties`` dictionary using the :class:`_schema.Column`
343
- element directly.
344
- Use this function when the given column is not directly present within
345
- the mapper's selectable; examples include SQL expressions, functions,
346
- and scalar SELECT queries.
370
+ With Declarative mappings, :func:`_orm.column_property` is used to
371
+ map read-only SQL expressions to a mapped class.
372
+
373
+ When using Imperative mappings, :func:`_orm.column_property` also
374
+ takes on the role of mapping table columns with additional features.
375
+ When using fully Declarative mappings, the :func:`_orm.mapped_column`
376
+ construct should be used for this purpose.
377
+
378
+ With Declarative Dataclass mappings, :func:`_orm.column_property`
379
+ is considered to be **read only**, and will not be included in the
380
+ Dataclass ``__init__()`` constructor.
347
381
348
382
The :func:`_orm.column_property` function returns an instance of
349
383
:class:`.ColumnProperty`.
350
384
351
- Columns that aren't present in the mapper's selectable won't be
352
- persisted by the mapper and are effectively "read-only" attributes.
385
+ .. seealso::
386
+
387
+ :ref:`mapper_column_property_sql_expressions` - general use of
388
+ :func:`_orm.column_property` to map SQL expressions
389
+
390
+ :ref:`orm_imperative_table_column_options` - usage of
391
+ :func:`_orm.column_property` with Imperative Table mappings to apply
392
+ additional options to a plain :class:`_schema.Column` object
353
393
354
394
:param \*cols:
355
- list of Column objects to be mapped.
395
+ list of Column objects to be mapped.
356
396
357
397
:param active_history=False:
358
- When ``True``, indicates that the "previous" value for a
359
- scalar attribute should be loaded when replaced, if not
360
- already loaded. Normally, history tracking logic for
361
- simple non-primary-key scalar values only needs to be
362
- aware of the "new" value in order to perform a flush. This
363
- flag is available for applications that make use of
364
- :func:`.attributes.get_history` or :meth:`.Session.is_modified`
365
- which also need to know
366
- the "previous" value of the attribute.
398
+
399
+ Used only for Imperative Table mappings, or legacy-style Declarative
400
+ mappings (i.e. which have not been upgraded to
401
+ :func:`_orm.mapped_column`), for column-based attributes that are
402
+ expected to be writeable; use :func:`_orm.mapped_column` with
403
+ :paramref:`_orm.mapped_column.active_history` for Declarative mappings.
404
+ See that parameter for functional details.
367
405
368
406
:param comparator_factory: a class which extends
369
- :class:`.ColumnProperty.Comparator` which provides custom SQL
370
- clause generation for comparison operations.
407
+ :class:`.ColumnProperty.Comparator` which provides custom SQL
408
+ clause generation for comparison operations.
371
409
372
410
:param group:
373
411
a group name for this property when marked as deferred.
374
412
375
413
:param deferred:
376
- when True, the column property is "deferred", meaning that
377
- it does not load immediately, and is instead loaded when the
378
- attribute is first accessed on an instance. See also
379
- :func:`~sqlalchemy.orm.deferred`.
414
+ when True, the column property is "deferred", meaning that
415
+ it does not load immediately, and is instead loaded when the
416
+ attribute is first accessed on an instance. See also
417
+ :func:`~sqlalchemy.orm.deferred`.
380
418
381
419
:param doc:
382
- optional string that will be applied as the doc on the
383
- class-bound descriptor.
420
+ optional string that will be applied as the doc on the
421
+ class-bound descriptor.
384
422
385
423
:param expire_on_flush=True:
386
424
Disable expiry on flush. A column_property() which refers
@@ -410,20 +448,25 @@ def column_property(
410
448
411
449
:ref:`orm_queryguide_deferred_raiseload`
412
450
413
- .. seealso::
451
+ :param init:
452
+
453
+ :param default:
414
454
415
- :ref:`column_property_options` - to map columns while including
416
- mapping options
455
+ :param default_factory:
417
456
418
- :ref:`mapper_column_property_sql_expressions` - to map SQL
419
- expressions
457
+ :param kw_only:
420
458
421
459
"""
422
460
return MappedSQLExpression (
423
461
column ,
424
462
* additional_columns ,
425
463
attribute_options = _AttributeOptions (
426
- init , repr , default , default_factory , compare , kw_only
464
+ False if init is _NoArg .NO_ARG else init ,
465
+ repr ,
466
+ default ,
467
+ default_factory ,
468
+ compare ,
469
+ kw_only ,
427
470
),
428
471
group = group ,
429
472
deferred = deferred ,
@@ -433,6 +476,7 @@ def column_property(
433
476
expire_on_flush = expire_on_flush ,
434
477
info = info ,
435
478
doc = doc ,
479
+ _assume_readonly_dc_attributes = True ,
436
480
)
437
481
438
482
@@ -2017,6 +2061,7 @@ def query_expression(
2017
2061
default_expr : _ORMColumnExprArgument [_T ] = sql .null (),
2018
2062
* ,
2019
2063
repr : Union [_NoArg , bool ] = _NoArg .NO_ARG , # noqa: A002
2064
+ compare : Union [_NoArg , bool ] = _NoArg .NO_ARG , # noqa: A002
2020
2065
expire_on_flush : bool = True ,
2021
2066
info : Optional [_InfoType ] = None ,
2022
2067
doc : Optional [str ] = None ,
@@ -2036,16 +2081,17 @@ def query_expression(
2036
2081
prop = MappedSQLExpression (
2037
2082
default_expr ,
2038
2083
attribute_options = _AttributeOptions (
2039
- _NoArg . NO_ARG ,
2084
+ False ,
2040
2085
repr ,
2041
2086
_NoArg .NO_ARG ,
2042
2087
_NoArg .NO_ARG ,
2043
- _NoArg . NO_ARG ,
2088
+ compare ,
2044
2089
_NoArg .NO_ARG ,
2045
2090
),
2046
2091
expire_on_flush = expire_on_flush ,
2047
2092
info = info ,
2048
2093
doc = doc ,
2094
+ _assume_readonly_dc_attributes = True ,
2049
2095
)
2050
2096
2051
2097
prop .strategy_key = (("query_expression" , True ),)
0 commit comments