Skip to content

Commit 93b21c2

Browse files
committed
Extra parameters for .lookup(), passed to .insert() - closes #342
1 parent 3b8abe6 commit 93b21c2

File tree

3 files changed

+110
-4
lines changed

3 files changed

+110
-4
lines changed

docs/python-api.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,17 @@ To create a species record with a note on when it was first seen, you can use th
834834
835835
The first time this is called the record will be created for ``name="Palm"``. Any subsequent calls with that name will ignore the second argument, even if it includes different values.
836836

837+
``.lookup()`` also accepts keyword arguments, which are passed through to the :ref:`insert() method <python_api_creating_tables>` and can be used to influence the shape of the created table. Supported parameters are:
838+
839+
- ``pk`` - which defaults to ``id``
840+
- ``foreign_keys``
841+
- ``column_order``
842+
- ``not_null``
843+
- ``defaults``
844+
- ``extracts``
845+
- ``conversions``
846+
- ``columns``
847+
837848
.. _python_api_extracts:
838849

839850
Populating lookup tables automatically during insert/upsert

sqlite_utils/db.py

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2556,7 +2556,7 @@ def insert_all(
25562556
ignore = self.value_or_default("ignore", ignore)
25572557
replace = self.value_or_default("replace", replace)
25582558
extracts = self.value_or_default("extracts", extracts)
2559-
conversions = self.value_or_default("conversions", conversions)
2559+
conversions = self.value_or_default("conversions", conversions) or {}
25602560
columns = self.value_or_default("columns", columns)
25612561

25622562
if upsert and (not pk and not hash_id):
@@ -2718,6 +2718,14 @@ def lookup(
27182718
self,
27192719
lookup_values: Dict[str, Any],
27202720
extra_values: Optional[Dict[str, Any]] = None,
2721+
pk: Optional[str] = "id",
2722+
foreign_keys: Optional[ForeignKeysType] = None,
2723+
column_order: Optional[List[str]] = None,
2724+
not_null: Optional[Set[str]] = None,
2725+
defaults: Optional[Dict[str, Any]] = None,
2726+
extracts: Optional[Union[Dict[str, str], List[str]]] = None,
2727+
conversions: Optional[Dict[str, str]] = None,
2728+
columns: Optional[Dict[str, Any]] = None,
27212729
):
27222730
"""
27232731
Create or populate a lookup table with the specified values.
@@ -2735,6 +2743,8 @@ def lookup(
27352743
be ignored on subsequent lookup calls for records that already exist.
27362744
27372745
See :ref:`python_api_lookup_tables` for more details.
2746+
2747+
All other keyword arguments are passed through to ``.insert()``.
27382748
"""
27392749
assert isinstance(lookup_values, dict)
27402750
if extra_values is not None:
@@ -2754,11 +2764,31 @@ def lookup(
27542764
)
27552765
)
27562766
try:
2757-
return rows[0]["id"]
2767+
return rows[0][pk]
27582768
except IndexError:
2759-
return self.insert(combined_values, pk="id").last_pk
2769+
return self.insert(
2770+
combined_values,
2771+
pk=pk,
2772+
foreign_keys=foreign_keys,
2773+
column_order=column_order,
2774+
not_null=not_null,
2775+
defaults=defaults,
2776+
extracts=extracts,
2777+
conversions=conversions,
2778+
columns=columns,
2779+
).last_pk
27602780
else:
2761-
pk = self.insert(combined_values, pk="id").last_pk
2781+
pk = self.insert(
2782+
combined_values,
2783+
pk=pk,
2784+
foreign_keys=foreign_keys,
2785+
column_order=column_order,
2786+
not_null=not_null,
2787+
defaults=defaults,
2788+
extracts=extracts,
2789+
conversions=conversions,
2790+
columns=columns,
2791+
).last_pk
27622792
self.create_index(lookup_values.keys(), unique=True)
27632793
return pk
27642794

tests/test_lookup.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,68 @@ def test_lookup_with_extra_values(fresh_db):
8686
"type": "Tree",
8787
"first_seen": "2020-01-01",
8888
}
89+
90+
91+
def test_lookup_with_extra_insert_parameters(fresh_db):
92+
other_table = fresh_db["other_table"]
93+
other_table.insert({"id": 1, "name": "Name"}, pk="id")
94+
species = fresh_db["species"]
95+
id = species.lookup(
96+
{"name": "Palm", "type": "Tree"},
97+
{
98+
"first_seen": "2020-01-01",
99+
"make_not_null": 1,
100+
"fk_to_other": 1,
101+
"default_is_dog": "cat",
102+
"extract_this": "This is extracted",
103+
"convert_to_upper": "upper",
104+
"make_this_integer": "2",
105+
"this_at_front": 1,
106+
},
107+
pk="renamed_id",
108+
foreign_keys=(("fk_to_other", "other_table", "id"),),
109+
column_order=("this_at_front",),
110+
not_null={"make_not_null"},
111+
defaults={"default_is_dog": "dog"},
112+
extracts=["extract_this"],
113+
conversions={"convert_to_upper": "upper(?)"},
114+
columns={"make_this_integer": int},
115+
)
116+
assert species.schema == (
117+
"CREATE TABLE [species] (\n"
118+
" [renamed_id] INTEGER PRIMARY KEY,\n"
119+
" [this_at_front] INTEGER,\n"
120+
" [name] TEXT,\n"
121+
" [type] TEXT,\n"
122+
" [first_seen] TEXT,\n"
123+
" [make_not_null] INTEGER NOT NULL,\n"
124+
" [fk_to_other] INTEGER REFERENCES [other_table]([id]),\n"
125+
" [default_is_dog] TEXT DEFAULT 'dog',\n"
126+
" [extract_this] INTEGER REFERENCES [extract_this]([id]),\n"
127+
" [convert_to_upper] TEXT,\n"
128+
" [make_this_integer] INTEGER\n"
129+
")"
130+
)
131+
assert species.get(id) == {
132+
"renamed_id": id,
133+
"this_at_front": 1,
134+
"name": "Palm",
135+
"type": "Tree",
136+
"first_seen": "2020-01-01",
137+
"make_not_null": 1,
138+
"fk_to_other": 1,
139+
"default_is_dog": "cat",
140+
"extract_this": 1,
141+
"convert_to_upper": "UPPER",
142+
"make_this_integer": 2,
143+
}
144+
assert species.indexes == [
145+
Index(
146+
seq=0,
147+
name="idx_species_name_type",
148+
unique=1,
149+
origin="c",
150+
partial=0,
151+
columns=["name", "type"],
152+
)
153+
]

0 commit comments

Comments
 (0)