table.m2m(..., alter=True) option, closes #222

This commit is contained in:
Simon Willison 2021-01-17 20:26:02 -08:00
commit d4e00f8d01
3 changed files with 24 additions and 1 deletions

View file

@ -716,6 +716,8 @@ If it cannot find such a table, it will create a new one using the names of the
It it finds multiple candidate tables with foreign keys to both of the specified tables it will raise a ``sqlite_utils.db.NoObviousTable`` exception. You can avoid this error by specifying the correct table using ``m2m_table=``.
The ``.m2m()`` method also takes an optional ``pk=`` argument to specify the primary key that should be used if the table is created, and an optional ``alter=True`` argument to specify that any missing columns of an existing table should be added if they are needed.
.. _python_api_m2m_lookup:
Using m2m and lookup tables together

View file

@ -2009,6 +2009,7 @@ class Table(Queryable):
pk=DEFAULT,
lookup=None,
m2m_table=None,
alter=False,
):
if isinstance(other_table, str):
other_table = self.db.table(other_table, pk=pk)
@ -2045,7 +2046,9 @@ class Table(Queryable):
)
# Ensure each record exists in other table
for record in records:
id = other_table.insert(record, pk=pk, replace=True).last_pk
id = other_table.insert(
record, pk=pk, replace=True, alter=alter
).last_pk
m2m_table.insert(
{
"{}_id".format(other_table.name): id,

View file

@ -14,6 +14,24 @@ def test_insert_m2m_single(fresh_db):
assert [{"humans_id": 1, "dogs_id": 1}] == list(dogs_humans.rows)
def test_insert_m2m_alter(fresh_db):
dogs = fresh_db["dogs"]
dogs.insert({"id": 1, "name": "Cleo"}, pk="id").m2m(
"humans", {"id": 1, "name": "Natalie D"}, pk="id"
)
dogs.update(1).m2m(
"humans", {"id": 2, "name": "Simon W", "nerd": True}, pk="id", alter=True
)
assert list(fresh_db["humans"].rows) == [
{"id": 1, "name": "Natalie D", "nerd": None},
{"id": 2, "name": "Simon W", "nerd": 1},
]
assert list(fresh_db["dogs_humans"].rows) == [
{"humans_id": 1, "dogs_id": 1},
{"humans_id": 2, "dogs_id": 1},
]
def test_insert_m2m_list(fresh_db):
dogs = fresh_db["dogs"]
dogs.insert({"id": 1, "name": "Cleo"}, pk="id").m2m(