sqlite-utils 3.38__py3-none-any.whl → 3.39__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- sqlite_utils/cli.py +35 -9
- sqlite_utils/db.py +10 -3
- {sqlite_utils-3.38.dist-info → sqlite_utils-3.39.dist-info}/METADATA +18 -7
- {sqlite_utils-3.38.dist-info → sqlite_utils-3.39.dist-info}/RECORD +8 -8
- {sqlite_utils-3.38.dist-info → sqlite_utils-3.39.dist-info}/WHEEL +1 -1
- {sqlite_utils-3.38.dist-info → sqlite_utils-3.39.dist-info}/entry_points.txt +0 -0
- {sqlite_utils-3.38.dist-info → sqlite_utils-3.39.dist-info/licenses}/LICENSE +0 -0
- {sqlite_utils-3.38.dist-info → sqlite_utils-3.39.dist-info}/top_level.txt +0 -0
sqlite_utils/cli.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import base64
|
|
2
2
|
import click
|
|
3
3
|
from click_default_group import DefaultGroup # type: ignore
|
|
4
|
-
from datetime import datetime
|
|
4
|
+
from datetime import datetime, timezone
|
|
5
5
|
import hashlib
|
|
6
6
|
import pathlib
|
|
7
7
|
from runpy import run_module
|
|
@@ -962,7 +962,7 @@ def insert_upsert_implementation(
|
|
|
962
962
|
db = sqlite_utils.Database(path)
|
|
963
963
|
_load_extensions(db, load_extension)
|
|
964
964
|
if functions:
|
|
965
|
-
|
|
965
|
+
_register_functions_from_multiple(db, functions)
|
|
966
966
|
if (delimiter or quotechar or sniff or no_headers) and not tsv:
|
|
967
967
|
csv = True
|
|
968
968
|
if (nl + csv + tsv) >= 2:
|
|
@@ -1370,7 +1370,9 @@ def upsert(
|
|
|
1370
1370
|
@click.argument("file", type=click.File("rb"), required=True)
|
|
1371
1371
|
@click.option("--batch-size", type=int, default=100, help="Commit every X records")
|
|
1372
1372
|
@click.option(
|
|
1373
|
-
"--functions",
|
|
1373
|
+
"--functions",
|
|
1374
|
+
help="Python code or file path defining custom SQL functions",
|
|
1375
|
+
multiple=True,
|
|
1374
1376
|
)
|
|
1375
1377
|
@import_options
|
|
1376
1378
|
@load_extension_option
|
|
@@ -1759,7 +1761,9 @@ def drop_view(path, view, ignore, load_extension):
|
|
|
1759
1761
|
help="Named :parameters for SQL query",
|
|
1760
1762
|
)
|
|
1761
1763
|
@click.option(
|
|
1762
|
-
"--functions",
|
|
1764
|
+
"--functions",
|
|
1765
|
+
help="Python code or file path defining custom SQL functions",
|
|
1766
|
+
multiple=True,
|
|
1763
1767
|
)
|
|
1764
1768
|
@load_extension_option
|
|
1765
1769
|
def query(
|
|
@@ -1796,7 +1800,7 @@ def query(
|
|
|
1796
1800
|
db.register_fts4_bm25()
|
|
1797
1801
|
|
|
1798
1802
|
if functions:
|
|
1799
|
-
|
|
1803
|
+
_register_functions_from_multiple(db, functions)
|
|
1800
1804
|
|
|
1801
1805
|
_execute_query(
|
|
1802
1806
|
db,
|
|
@@ -1824,7 +1828,9 @@ def query(
|
|
|
1824
1828
|
)
|
|
1825
1829
|
@click.argument("sql")
|
|
1826
1830
|
@click.option(
|
|
1827
|
-
"--functions",
|
|
1831
|
+
"--functions",
|
|
1832
|
+
help="Python code or file path defining custom SQL functions",
|
|
1833
|
+
multiple=True,
|
|
1828
1834
|
)
|
|
1829
1835
|
@click.option(
|
|
1830
1836
|
"--attach",
|
|
@@ -1996,7 +2002,7 @@ def memory(
|
|
|
1996
2002
|
db.register_fts4_bm25()
|
|
1997
2003
|
|
|
1998
2004
|
if functions:
|
|
1999
|
-
|
|
2005
|
+
_register_functions_from_multiple(db, functions)
|
|
2000
2006
|
|
|
2001
2007
|
if return_db:
|
|
2002
2008
|
return db
|
|
@@ -3203,8 +3209,12 @@ FILE_COLUMNS = {
|
|
|
3203
3209
|
"ctime": lambda p: p.stat().st_ctime,
|
|
3204
3210
|
"mtime_int": lambda p: int(p.stat().st_mtime),
|
|
3205
3211
|
"ctime_int": lambda p: int(p.stat().st_ctime),
|
|
3206
|
-
"mtime_iso": lambda p: datetime.
|
|
3207
|
-
|
|
3212
|
+
"mtime_iso": lambda p: datetime.fromtimestamp(p.stat().st_mtime, timezone.utc)
|
|
3213
|
+
.replace(tzinfo=None)
|
|
3214
|
+
.isoformat(),
|
|
3215
|
+
"ctime_iso": lambda p: datetime.fromtimestamp(p.stat().st_ctime, timezone.utc)
|
|
3216
|
+
.replace(tzinfo=None)
|
|
3217
|
+
.isoformat(),
|
|
3208
3218
|
"size": lambda p: p.stat().st_size,
|
|
3209
3219
|
"stem": lambda p: p.stem,
|
|
3210
3220
|
"suffix": lambda p: p.suffix,
|
|
@@ -3281,6 +3291,13 @@ def _load_extensions(db, load_extension):
|
|
|
3281
3291
|
|
|
3282
3292
|
def _register_functions(db, functions):
|
|
3283
3293
|
# Register any Python functions as SQL functions:
|
|
3294
|
+
# Check if this is a file path
|
|
3295
|
+
if "\n" not in functions and functions.endswith(".py"):
|
|
3296
|
+
try:
|
|
3297
|
+
functions = pathlib.Path(functions).read_text()
|
|
3298
|
+
except FileNotFoundError:
|
|
3299
|
+
raise click.ClickException("File not found: {}".format(functions))
|
|
3300
|
+
|
|
3284
3301
|
sqlite3.enable_callback_tracebacks(True)
|
|
3285
3302
|
globals = {}
|
|
3286
3303
|
try:
|
|
@@ -3291,3 +3308,12 @@ def _register_functions(db, functions):
|
|
|
3291
3308
|
for name, value in globals.items():
|
|
3292
3309
|
if callable(value) and not name.startswith("_"):
|
|
3293
3310
|
db.register_function(value, name=name)
|
|
3311
|
+
|
|
3312
|
+
|
|
3313
|
+
def _register_functions_from_multiple(db, functions_list):
|
|
3314
|
+
"""Register functions from multiple --functions arguments."""
|
|
3315
|
+
if not functions_list:
|
|
3316
|
+
return
|
|
3317
|
+
for functions in functions_list:
|
|
3318
|
+
if isinstance(functions, str) and functions.strip():
|
|
3319
|
+
_register_functions(db, functions)
|
sqlite_utils/db.py
CHANGED
|
@@ -237,36 +237,43 @@ if pd:
|
|
|
237
237
|
|
|
238
238
|
class AlterError(Exception):
|
|
239
239
|
"Error altering table"
|
|
240
|
+
|
|
240
241
|
pass
|
|
241
242
|
|
|
242
243
|
|
|
243
244
|
class NoObviousTable(Exception):
|
|
244
245
|
"Could not tell which table this operation refers to"
|
|
246
|
+
|
|
245
247
|
pass
|
|
246
248
|
|
|
247
249
|
|
|
248
250
|
class NoTable(Exception):
|
|
249
251
|
"Specified table does not exist"
|
|
252
|
+
|
|
250
253
|
pass
|
|
251
254
|
|
|
252
255
|
|
|
253
256
|
class BadPrimaryKey(Exception):
|
|
254
257
|
"Table does not have a single obvious primary key"
|
|
258
|
+
|
|
255
259
|
pass
|
|
256
260
|
|
|
257
261
|
|
|
258
262
|
class NotFoundError(Exception):
|
|
259
263
|
"Record not found"
|
|
264
|
+
|
|
260
265
|
pass
|
|
261
266
|
|
|
262
267
|
|
|
263
268
|
class PrimaryKeyRequired(Exception):
|
|
264
269
|
"Primary key needs to be specified"
|
|
270
|
+
|
|
265
271
|
pass
|
|
266
272
|
|
|
267
273
|
|
|
268
274
|
class InvalidColumns(Exception):
|
|
269
275
|
"Specified columns do not exist"
|
|
276
|
+
|
|
270
277
|
pass
|
|
271
278
|
|
|
272
279
|
|
|
@@ -368,7 +375,7 @@ class Database:
|
|
|
368
375
|
pm.hook.prepare_connection(conn=self.conn)
|
|
369
376
|
self.strict = strict
|
|
370
377
|
|
|
371
|
-
def close(self):
|
|
378
|
+
def close(self) -> None:
|
|
372
379
|
"Close the SQLite connection, and the underlying database file"
|
|
373
380
|
self.conn.close()
|
|
374
381
|
|
|
@@ -3203,7 +3210,7 @@ class Table(Queryable):
|
|
|
3203
3210
|
:param not_null: Set of strings specifying columns that should be ``NOT NULL``.
|
|
3204
3211
|
:param defaults: Dictionary specifying default values for specific columns.
|
|
3205
3212
|
:param hash_id: Name of a column to create and use as a primary key, where the
|
|
3206
|
-
value of
|
|
3213
|
+
value of that primary key will be derived as a SHA1 hash of the other column values
|
|
3207
3214
|
in the record. ``hash_id="id"`` is a common column name used for this.
|
|
3208
3215
|
:param alter: Boolean, should any missing columns be added automatically?
|
|
3209
3216
|
:param ignore: Boolean, if a record already exists with this primary key, ignore this insert.
|
|
@@ -3852,7 +3859,7 @@ def jsonify_if_needed(value):
|
|
|
3852
3859
|
|
|
3853
3860
|
|
|
3854
3861
|
def resolve_extracts(
|
|
3855
|
-
extracts: Optional[Union[Dict[str, str], List[str], Tuple[str]]]
|
|
3862
|
+
extracts: Optional[Union[Dict[str, str], List[str], Tuple[str]]],
|
|
3856
3863
|
) -> dict:
|
|
3857
3864
|
if extracts is None:
|
|
3858
3865
|
extracts = {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: sqlite-utils
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.39
|
|
4
4
|
Summary: CLI tool and Python library for manipulating SQLite databases
|
|
5
5
|
Home-page: https://github.com/simonw/sqlite-utils
|
|
6
6
|
Author: Simon Willison
|
|
@@ -15,22 +15,21 @@ Classifier: Intended Audience :: Developers
|
|
|
15
15
|
Classifier: Intended Audience :: Science/Research
|
|
16
16
|
Classifier: Intended Audience :: End Users/Desktop
|
|
17
17
|
Classifier: Topic :: Database
|
|
18
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
19
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
21
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
22
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
23
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
24
21
|
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
-
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Requires-Python: >=3.10
|
|
26
24
|
Description-Content-Type: text/markdown
|
|
27
25
|
License-File: LICENSE
|
|
28
26
|
Requires-Dist: sqlite-fts4
|
|
29
|
-
Requires-Dist: click
|
|
27
|
+
Requires-Dist: click>=8.3.1
|
|
30
28
|
Requires-Dist: click-default-group>=1.2.3
|
|
31
29
|
Requires-Dist: tabulate
|
|
32
30
|
Requires-Dist: python-dateutil
|
|
33
31
|
Requires-Dist: pluggy
|
|
32
|
+
Requires-Dist: pip
|
|
34
33
|
Provides-Extra: test
|
|
35
34
|
Requires-Dist: pytest; extra == "test"
|
|
36
35
|
Requires-Dist: black>=24.1.1; extra == "test"
|
|
@@ -54,6 +53,18 @@ Provides-Extra: flake8
|
|
|
54
53
|
Requires-Dist: flake8; extra == "flake8"
|
|
55
54
|
Provides-Extra: tui
|
|
56
55
|
Requires-Dist: trogon; extra == "tui"
|
|
56
|
+
Dynamic: author
|
|
57
|
+
Dynamic: classifier
|
|
58
|
+
Dynamic: description
|
|
59
|
+
Dynamic: description-content-type
|
|
60
|
+
Dynamic: home-page
|
|
61
|
+
Dynamic: license
|
|
62
|
+
Dynamic: license-file
|
|
63
|
+
Dynamic: project-url
|
|
64
|
+
Dynamic: provides-extra
|
|
65
|
+
Dynamic: requires-dist
|
|
66
|
+
Dynamic: requires-python
|
|
67
|
+
Dynamic: summary
|
|
57
68
|
|
|
58
69
|
# sqlite-utils
|
|
59
70
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
sqlite_utils/__init__.py,sha256=eyDK-5KOo-ARS3i0JcuxGiJmk5T-58Z1p_bhACbBrGc,201
|
|
2
2
|
sqlite_utils/__main__.py,sha256=8hDtWlaFZK24KhfNq_ZKgtXqYHsDQDetukOCMlsbW0Q,59
|
|
3
|
-
sqlite_utils/cli.py,sha256=
|
|
4
|
-
sqlite_utils/db.py,sha256=
|
|
3
|
+
sqlite_utils/cli.py,sha256=aFaRae_sFxpYXwivUqPTkkUWamcqOB-GpDaz2nWzIBg,90639
|
|
4
|
+
sqlite_utils/db.py,sha256=wMKAYDTr9LshEfd4prvHdKigIwcEWcx1sA-i5IR4pV0,148525
|
|
5
5
|
sqlite_utils/hookspecs.py,sha256=NFA0BFZ8WUhnI_NRz4oFVDcomQYlguuAgUCBKAN792o,395
|
|
6
6
|
sqlite_utils/plugins.py,sha256=V5nXD4r0o1wSbIHHOAiUBBV66ZOfKVnywKfZzCUqdsA,771
|
|
7
7
|
sqlite_utils/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
sqlite_utils/recipes.py,sha256=_npzti0nPV6XxvMj69Ca4QF-pXwZZQp_f_VY3i7pQDs,1687
|
|
9
9
|
sqlite_utils/utils.py,sha256=PRqoITtqmaUI7xzyB2exaTPg6oXbTMhGDzld7srNOG4,17099
|
|
10
|
-
sqlite_utils-3.
|
|
11
|
-
sqlite_utils-3.
|
|
12
|
-
sqlite_utils-3.
|
|
13
|
-
sqlite_utils-3.
|
|
14
|
-
sqlite_utils-3.
|
|
15
|
-
sqlite_utils-3.
|
|
10
|
+
sqlite_utils-3.39.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
11
|
+
sqlite_utils-3.39.dist-info/METADATA,sha256=Ytv9XEkJTpIkRgP_UdDpkXW6wp0281JYyJ2wBuaDICs,7714
|
|
12
|
+
sqlite_utils-3.39.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
+
sqlite_utils-3.39.dist-info/entry_points.txt,sha256=33jbVHROlRBNhoXoSI-QI2rN6JDkJIkKIX7P5sNIWdY,54
|
|
14
|
+
sqlite_utils-3.39.dist-info/top_level.txt,sha256=_dw_n5BWKUEtCYB2DTlmPMQfdRZSuFsmRQe2ZhNYwnQ,13
|
|
15
|
+
sqlite_utils-3.39.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|