Sort a collection of :class:`_schema.Table` / :class:`_schema.ForeignKeyConstraint` objects. This is a dependency-ordered sort which will emit tuples of ``(Table, [ForeignKeyConstraint, ...])`` such that each :class:`_schema.Table` follows its dependent :class:`_schema.Table`
(
tables, filter_fn=None, extra_dependencies=None, _warn_for_cycles=False
)
| 1793 | |
| 1794 | @util.preload_module("sqlalchemy.sql.schema") |
| 1795 | def sort_tables_and_constraints( |
| 1796 | tables, filter_fn=None, extra_dependencies=None, _warn_for_cycles=False |
| 1797 | ): |
| 1798 | """Sort a collection of :class:`_schema.Table` / |
| 1799 | :class:`_schema.ForeignKeyConstraint` |
| 1800 | objects. |
| 1801 | |
| 1802 | This is a dependency-ordered sort which will emit tuples of |
| 1803 | ``(Table, [ForeignKeyConstraint, ...])`` such that each |
| 1804 | :class:`_schema.Table` follows its dependent :class:`_schema.Table` |
| 1805 | objects. |
| 1806 | Remaining :class:`_schema.ForeignKeyConstraint` |
| 1807 | objects that are separate due to |
| 1808 | dependency rules not satisfied by the sort are emitted afterwards |
| 1809 | as ``(None, [ForeignKeyConstraint ...])``. |
| 1810 | |
| 1811 | Tables are dependent on another based on the presence of |
| 1812 | :class:`_schema.ForeignKeyConstraint` objects, explicit dependencies |
| 1813 | added by :meth:`_schema.Table.add_is_dependent_on`, |
| 1814 | as well as dependencies |
| 1815 | stated here using the :paramref:`~.sort_tables_and_constraints.skip_fn` |
| 1816 | and/or :paramref:`~.sort_tables_and_constraints.extra_dependencies` |
| 1817 | parameters. |
| 1818 | |
| 1819 | :param tables: a sequence of :class:`_schema.Table` objects. |
| 1820 | |
| 1821 | :param filter_fn: optional callable which will be passed a |
| 1822 | :class:`_schema.ForeignKeyConstraint` object, |
| 1823 | and returns a value based on |
| 1824 | whether this constraint should definitely be included or excluded as |
| 1825 | an inline constraint, or neither. If it returns False, the constraint |
| 1826 | will definitely be included as a dependency that cannot be subject |
| 1827 | to ALTER; if True, it will **only** be included as an ALTER result at |
| 1828 | the end. Returning None means the constraint is included in the |
| 1829 | table-based result unless it is detected as part of a dependency cycle. |
| 1830 | |
| 1831 | :param extra_dependencies: a sequence of 2-tuples of tables which will |
| 1832 | also be considered as dependent on each other. |
| 1833 | |
| 1834 | .. seealso:: |
| 1835 | |
| 1836 | :func:`.sort_tables` |
| 1837 | |
| 1838 | |
| 1839 | """ |
| 1840 | Table = util.preloaded.sql_schema.Table |
| 1841 | |
| 1842 | fixed_dependencies = set() |
| 1843 | mutable_dependencies = set() |
| 1844 | |
| 1845 | if extra_dependencies is not None: |
| 1846 | fixed_dependencies.update(extra_dependencies) |
| 1847 | |
| 1848 | remaining_fkcs = set() |
| 1849 | for table in tables: |
| 1850 | for fkc in table.foreign_key_constraints: |
| 1851 | if fkc.use_alter is True: |
| 1852 | remaining_fkcs.add(fkc) |
no test coverage detected