db.m2m_table_candidates(table, other_table)

This commit is contained in:
Simon Willison 2019-08-03 21:07:06 +03:00
commit b9256413d2
2 changed files with 33 additions and 0 deletions

View file

@ -297,6 +297,17 @@ class Database:
)
)
def m2m_table_candidates(self, table, other_table):
"Returns potential m2m tables for arguments, based on FKs"
candidates = []
tables = {table, other_table}
for table in self.tables:
# Does it have foreign keys to both table and other_table?
has_fks_to = {fk.other_table for fk in table.foreign_keys}
if has_fks_to.issuperset(tables):
candidates.append(table.name)
return candidates
def add_foreign_keys(self, foreign_keys):
# foreign_keys is a list of explicit 4-tuples
assert all(

View file

@ -84,6 +84,28 @@ def test_m2m_explicit_table_name_argument(fresh_db):
assert not fresh_db["people_tags"].exists
def test_m2m_table_candidates(fresh_db):
fresh_db.create_table("one", {"id": int, "name": str}, pk="id")
fresh_db.create_table("two", {"id": int, "name": str}, pk="id")
fresh_db.create_table("three", {"id": int, "name": str}, pk="id")
# No candidates at first
assert [] == fresh_db.m2m_table_candidates("one", "two")
# Create a candidate
fresh_db.create_table(
"one_m2m_two", {"one_id": int, "two_id": int}, foreign_keys=["one_id", "two_id"]
)
assert ["one_m2m_two"] == fresh_db.m2m_table_candidates("one", "two")
# Add another table and there should be two candidates
fresh_db.create_table(
"one_m2m_two_and_three",
{"one_id": int, "two_id": int, "three_id": int},
foreign_keys=["one_id", "two_id", "three_id"],
)
assert {"one_m2m_two", "one_m2m_two_and_three"} == set(
fresh_db.m2m_table_candidates("one", "two")
)
def test_uses_existing_m2m_table_if_exists(fresh_db):
# Code should look for an existing toble with fks to both tables
# and use that if it exists.