from __future__ import annotations
import typing
-from typing import Any
+from typing import Any, Mapping
from typing import Callable
from typing import Collection
from typing import Iterable
system: bool = False,
comment: Optional[str] = None,
sort_order: Union[_NoArg, int] = _NoArg.NO_ARG,
+ dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
**kw: Any,
) -> MappedColumn[Any]:
r"""declare a new ORM-mapped :class:`_schema.Column` construct
autoincrement=autoincrement,
insert_default=insert_default,
attribute_options=_AttributeOptions(
- init, repr, default, default_factory, compare, kw_only, hash
+ init,
+ repr,
+ default,
+ default_factory,
+ compare,
+ kw_only,
+ hash,
+ dataclass_metadata,
),
doc=doc,
key=key,
expire_on_flush: bool = True,
info: Optional[_InfoType] = None,
doc: Optional[str] = None,
+ dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
) -> MappedSQLExpression[_T]:
r"""Provide a column-level property for use with a mapping.
compare,
kw_only,
hash,
+ dataclass_metadata,
),
group=group,
deferred=deferred,
hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
info: Optional[_InfoType] = None,
doc: Optional[str] = None,
+ dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
**__kw: Any,
) -> Composite[Any]: ...
hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
info: Optional[_InfoType] = None,
doc: Optional[str] = None,
+ dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
**__kw: Any,
) -> Composite[Any]:
r"""Return a composite column-based property for use with a Mapper.
_class_or_attr,
*attrs,
attribute_options=_AttributeOptions(
- init, repr, default, default_factory, compare, kw_only, hash
+ init,
+ repr,
+ default,
+ default_factory,
+ compare,
+ kw_only,
+ hash,
+ dataclass_metadata,
),
group=group,
deferred=deferred,
info: Optional[_InfoType] = None,
omit_join: Literal[None, False] = None,
sync_backref: Optional[bool] = None,
+ dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
**kw: Any,
) -> _RelationshipDeclared[Any]:
"""Provide a relationship between two mapped classes.
cascade=cascade,
viewonly=viewonly,
attribute_options=_AttributeOptions(
- init, repr, default, default_factory, compare, kw_only, hash
+ init,
+ repr,
+ default,
+ default_factory,
+ compare,
+ kw_only,
+ hash,
+ dataclass_metadata,
),
lazy=lazy,
passive_deletes=passive_deletes,
hash: Union[_NoArg, bool, None] = _NoArg.NO_ARG, # noqa: A002
info: Optional[_InfoType] = None,
doc: Optional[str] = None,
+ dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
) -> Synonym[Any]:
"""Denote an attribute name as a synonym to a mapped property,
in that the attribute will mirror the value and expression behavior
descriptor=descriptor,
comparator_factory=comparator_factory,
attribute_options=_AttributeOptions(
- init, repr, default, default_factory, compare, kw_only, hash
+ init,
+ repr,
+ default,
+ default_factory,
+ compare,
+ kw_only,
+ hash,
+ dataclass_metadata,
),
doc=doc,
info=info,
expire_on_flush: bool = True,
info: Optional[_InfoType] = None,
doc: Optional[str] = None,
+ dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None] = _NoArg.NO_ARG,
) -> MappedSQLExpression[_T]:
r"""Indicate a column-based mapped attribute that by default will
not load unless accessed.
column,
*additional_columns,
attribute_options=_AttributeOptions(
- init, repr, default, default_factory, compare, kw_only, hash
+ init,
+ repr,
+ default,
+ default_factory,
+ compare,
+ kw_only,
+ hash,
+ dataclass_metadata,
),
group=group,
deferred=True,
compare,
_NoArg.NO_ARG,
_NoArg.NO_ARG,
+ _NoArg.NO_ARG,
),
expire_on_flush=expire_on_flush,
info=info,
import collections
import dataclasses
import typing
-from typing import Any
+from typing import Any, Mapping
from typing import Callable
from typing import cast
from typing import ClassVar
dataclasses_compare: Union[_NoArg, bool]
dataclasses_kw_only: Union[_NoArg, bool]
dataclasses_hash: Union[_NoArg, bool, None]
+ dataclasses_dataclass_metadata: Union[_NoArg, Mapping[Any, Any], None]
def _as_dataclass_field(
self, key: str, dataclass_setup_arguments: _DataclassArguments
kw["kw_only"] = self.dataclasses_kw_only
if self.dataclasses_hash is not _NoArg.NO_ARG:
kw["hash"] = self.dataclasses_hash
+ if self.dataclasses_dataclass_metadata is not _NoArg.NO_ARG:
+ kw["metadata"] = self.dataclasses_dataclass_metadata
if "default" in kw and callable(kw["default"]):
# callable defaults are ambiguous. deprecate them in favour of
_NoArg.NO_ARG,
_NoArg.NO_ARG,
_NoArg.NO_ARG,
+ _NoArg.NO_ARG,
)
_DEFAULT_READONLY_ATTRIBUTE_OPTIONS = _AttributeOptions(
_NoArg.NO_ARG,
_NoArg.NO_ARG,
_NoArg.NO_ARG,
+ _NoArg.NO_ARG,
)
from sqlalchemy.testing import expect_raises
from sqlalchemy.testing import expect_raises_message
from sqlalchemy.testing import fixtures
+from sqlalchemy.testing import in_
from sqlalchemy.testing import is_
from sqlalchemy.testing import is_false
from sqlalchemy.testing import is_true
eq_(fields["value"].default, cd)
eq_(fields["no_init"].default, cd)
+ def test_dataclass_metadata(self, dc_decl_base):
+ class A(dc_decl_base):
+ __tablename__ = "a"
+ id: Mapped[int] = mapped_column(primary_key=True)
+ value: Mapped[str] = mapped_column(
+ dataclass_metadata={"meta_key": "meta_value"}
+ )
+
+ fields = {f.name: f for f in dataclasses.fields(A)}
+
+ eq_(fields["id"].metadata, {})
+ eq_(fields["value"].metadata, {"meta_key": "meta_value"})
+
class RelationshipDefaultFactoryTest(fixtures.TestBase):
def test_list(self, dc_decl_base: Type[MappedAsDataclass]):
"compare": True,
"kw_only": False,
"hash": False,
+ "dataclass_metadata": None,
}
exp = interfaces._AttributeOptions(
- False, False, None, list, True, False, False
+ False, False, None, list, True, False, False, None
)
else:
kw = {}
True,
_NoArg.NO_ARG,
_NoArg.NO_ARG,
+ _NoArg.NO_ARG,
)
else:
kw = {}