summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/ext/automap.py
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/ext/automap.py')
-rw-r--r--lib/sqlalchemy/ext/automap.py46
1 files changed, 40 insertions, 6 deletions
diff --git a/lib/sqlalchemy/ext/automap.py b/lib/sqlalchemy/ext/automap.py
index 121285ab3..c11795d37 100644
--- a/lib/sqlalchemy/ext/automap.py
+++ b/lib/sqlalchemy/ext/automap.py
@@ -243,7 +243,26 @@ follows:
one-to-many backref will be created on the referred class referring
to this class.
-4. The names of the relationships are determined using the
+4. If any of the columns that are part of the :class:`.ForeignKeyConstraint`
+ are not nullable (e.g. ``nullable=False``), a
+ :paramref:`~.relationship.cascade` keyword argument
+ of ``all, delete-orphan`` will be added to the keyword arguments to
+ be passed to the relationship or backref. If the
+ :class:`.ForeignKeyConstraint` reports that
+ :paramref:`.ForeignKeyConstraint.ondelete`
+ is set to ``CASCADE`` for a not null or ``SET NULL`` for a nullable
+ set of columns, the option :paramref:`~.relationship.passive_deletes`
+ flag is set to ``True`` in the set of relationship keyword arguments.
+ Note that not all backends support reflection of ON DELETE.
+
+ .. versionadded:: 1.0.0 - automap will detect non-nullable foreign key
+ constraints when producing a one-to-many relationship and establish
+ a default cascade of ``all, delete-orphan`` if so; additionally,
+ if the constraint specifies :paramref:`.ForeignKeyConstraint.ondelete`
+ of ``CASCADE`` for non-nullable or ``SET NULL`` for nullable columns,
+ the ``passive_deletes=True`` option is also added.
+
+5. The names of the relationships are determined using the
:paramref:`.AutomapBase.prepare.name_for_scalar_relationship` and
:paramref:`.AutomapBase.prepare.name_for_collection_relationship`
callable functions. It is important to note that the default relationship
@@ -252,18 +271,18 @@ follows:
alternate class naming scheme, that's the name from which the relationship
name will be derived.
-5. The classes are inspected for an existing mapped property matching these
+6. The classes are inspected for an existing mapped property matching these
names. If one is detected on one side, but none on the other side,
:class:`.AutomapBase` attempts to create a relationship on the missing side,
then uses the :paramref:`.relationship.back_populates` parameter in order to
point the new relationship to the other side.
-6. In the usual case where no relationship is on either side,
+7. In the usual case where no relationship is on either side,
:meth:`.AutomapBase.prepare` produces a :func:`.relationship` on the
"many-to-one" side and matches it to the other using the
:paramref:`.relationship.backref` parameter.
-7. Production of the :func:`.relationship` and optionally the :func:`.backref`
+8. Production of the :func:`.relationship` and optionally the :func:`.backref`
is handed off to the :paramref:`.AutomapBase.prepare.generate_relationship`
function, which can be supplied by the end-user in order to augment
the arguments passed to :func:`.relationship` or :func:`.backref` or to
@@ -877,6 +896,19 @@ def _relationships_for_fks(automap_base, map_config, table_to_map_config,
constraint
)
+ o2m_kws = {}
+ nullable = False not in set([fk.parent.nullable for fk in fks])
+ if not nullable:
+ o2m_kws['cascade'] = "all, delete-orphan"
+
+ if constraint.ondelete and \
+ constraint.ondelete.lower() == "cascade":
+ o2m_kws['passive_deletes'] = True
+ else:
+ if constraint.ondelete and \
+ constraint.ondelete.lower() == "set null":
+ o2m_kws['passive_deletes'] = True
+
create_backref = backref_name not in referred_cfg.properties
if relationship_name not in map_config.properties:
@@ -885,7 +917,8 @@ def _relationships_for_fks(automap_base, map_config, table_to_map_config,
automap_base,
interfaces.ONETOMANY, backref,
backref_name, referred_cls, local_cls,
- collection_class=collection_class)
+ collection_class=collection_class,
+ **o2m_kws)
else:
backref_obj = None
rel = generate_relationship(automap_base,
@@ -916,7 +949,8 @@ def _relationships_for_fks(automap_base, map_config, table_to_map_config,
fk.parent
for fk in constraint.elements],
back_populates=relationship_name,
- collection_class=collection_class)
+ collection_class=collection_class,
+ **o2m_kws)
if rel is not None:
referred_cfg.properties[backref_name] = rel
map_config.properties[