# fastlite
<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->
`fastlite` provides some little quality-of-life improvements for
interactive use of the wonderful
[sqlite-utils](https://sqlite-utils.datasette.io/) library. It’s likely
to be particularly of interest to folks using Jupyter.
## Install
pip install fastlite
## Overview
``` python
from fastlite import *
from fastcore.utils import *
from fastcore.net import urlsave
```
We demonstrate `fastlite`‘s features here using the ’chinook’ sample
database.
``` python
url = 'https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite'
path = Path('chinook.sqlite')
if not path.exists(): urlsave(url, path)
db = database("chinook.sqlite")
```
Databases have a `t` property that lists all tables:
``` python
dt = db.t
dt
```
Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track
You can use this to grab a single table…:
``` python
artist = dt.artists
artist
```
<Table artists (does not exist yet)>
``` python
artist = dt.Artist
artist
```
<Table Artist (ArtistId, Name)>
…or multiple tables at once:
``` python
dt['Artist','Album','Track','Genre','MediaType']
```
[<Table Artist (ArtistId, Name)>,
<Table Album (AlbumId, Title, ArtistId)>,
<Table Track (TrackId, Name, AlbumId, MediaTypeId, GenreId, Composer, Milliseconds, Bytes, UnitPrice)>,
<Table Genre (GenreId, Name)>,
<Table MediaType (MediaTypeId, Name)>]
It also provides auto-complete in Jupyter, IPython, and nearly any other
interactive Python environment:
<img src="index_files/figure-commonmark/cell-16-1-image.png"
width="180" />
You can check if a table is in the database already:
``` python
'Artist' in dt
```
True
Column work in a similar way to tables, using the `c` property:
``` python
ac = artist.c
ac
```
ArtistId, Name
Auto-complete works for columns too:
<img src="index_files/figure-commonmark/cell-21-1-image.png"
width="140" />
Columns, tables, and view stringify in a format suitable for including
in SQL statements. That means you can use auto-complete in f-strings.
``` python
qry = f"select * from {artist} where {ac.Name} like 'AC/%'"
print(qry)
```
select * from "Artist" where "Artist"."Name" like 'AC/%'
You can view the results of a select query using `q`:
``` python
db.q(qry)
```
[{'ArtistId': 1, 'Name': 'AC/DC'}]
Views can be accessed through the `v` property:
``` python
album = dt.Album
acca_sql = f"""select {album}.*
from {album} join {artist} using (ArtistId)
where {ac.Name} like 'AC/%'"""
db.create_view("AccaDaccaAlbums", acca_sql, replace=True)
acca_dacca = db.q(f"select * from {db.v.AccaDaccaAlbums}")
acca_dacca
```
[{'AlbumId': 1,
'Title': 'For Those About To Rock We Salute You',
'ArtistId': 1},
{'AlbumId': 4, 'Title': 'Let There Be Rock', 'ArtistId': 1}]
## Dataclass support
A `dataclass` type with the names, types, and defaults of the tables is
created using `dataclass()`:
``` python
album_dc = album.dataclass()
```
Let’s try it:
``` python
album_obj = album_dc(**acca_dacca[0])
album_obj
```
Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1)
You can get the definition of the dataclass using fastcore’s
`dataclass_src` – everything is treated as nullable, in order to handle
auto-generated database values:
``` python
src = dataclass_src(album_dc)
hl_md(src, 'python')
```
``` python
@dataclass
class Album:
AlbumId: int | None = None
Title: str | None = None
ArtistId: int | None = None
```
Because `dataclass()` is dynamic, you won’t get auto-complete in editors
like vscode – it’ll only work in dynamic environments like Jupyter and
IPython. For editor support, you can export the full set of dataclasses
to a module, which you can then import from:
``` python
create_mod(db, 'db_dc')
```
``` python
from db_dc import Track
Track()
```
Track(TrackId=None, Name=None, AlbumId=None, MediaTypeId=None, GenreId=None, Composer=None, Milliseconds=None, Bytes=None, UnitPrice=None)
Indexing into a table does a query on primary key:
``` python
dt.Track[1]
```
Track(TrackId=1, Name='For Those About To Rock (We Salute You)', AlbumId=1, MediaTypeId=1, GenreId=1, Composer='Angus Young, Malcolm Young, Brian Johnson', Milliseconds=343719, Bytes=11170334, UnitPrice=0.99)
There’s a shortcut to select from a table – just call it as a function.
If you’ve previously called `dataclass()`, returned iterms will be
constructed using that class by default. There’s lots of params you can
check out, such as `limit`:
``` python
album(limit=2)
```
[Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1),
Album(AlbumId=2, Title='Balls to the Wall', ArtistId=2)]
Pass a truthy value as `with_pk` and you’ll get tuples of primary keys
and records:
``` python
album(with_pk=1, limit=2)
```
[(1,
Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1)),
(2, Album(AlbumId=2, Title='Balls to the Wall', ArtistId=2))]
Indexing also uses the dataclass by default:
``` python
album[5]
```
Album(AlbumId=5, Title='Big Ones', ArtistId=3)
If you set `xtra` fields, then indexing is also filtered by those. As a
result, for instance in this case, nothing is returned since album 5 is
not created by artist 1:
``` python
album.xtra(ArtistId=1)
try: album[5]
except NotFoundError: print("Not found")
```
Not found
The same filtering is done when using the table as a callable:
``` python
album()
```
[Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1),
Album(AlbumId=4, Title='Let There Be Rock', ArtistId=1)]
## Core design
The following methods accept `**kwargs`, passing them along to the first
`dict` param:
- `create`
- `transform`
- `transform_sql`
- `update`
- `insert`
- `upsert`
- `lookup`
We can access a table that doesn’t actually exist yet:
``` python
cats = dt.cats
cats
```
<Table cats (does not exist yet)>
We can use keyword arguments to now create that table:
``` python
cats.create(id=int, name=str, weight=float, uid=int, pk='id')
hl_md(cats.schema, 'sql')
```
``` sql
CREATE TABLE [cats] (
[id] INTEGER PRIMARY KEY,
[name] TEXT,
[weight] FLOAT,
[uid] INTEGER
)
```
It we set `xtra` then the additional fields are used for `insert`,
`update`, and `delete`:
``` python
cats.xtra(uid=2)
cat = cats.insert(name='meow', weight=6)
```
The inserted row is returned, including the xtra ‘uid’ field.
``` python
cat
```
{'id': 1, 'name': 'meow', 'weight': 6.0, 'uid': 2}
Using `**` in `update` here doesn’t actually achieve anything, since we
can just pass a `dict` directly – it’s just to show that it works:
``` python
cat['name'] = "moo"
cat['uid'] = 1
cats.update(**cat)
cats()
```
[{'id': 1, 'name': 'moo', 'weight': 6.0, 'uid': 2}]
Attempts to update or insert with xtra fields are ignored.
An error is raised if there’s an attempt to update a record not matching
`xtra` fields:
``` python
cats.xtra(uid=1)
try: cats.update(**cat)
except NotFoundError: print("Not found")
```
Not found
This all also works with dataclasses:
``` python
cats.xtra(uid=2)
cats.dataclass()
cat = cats[1]
cat
```
Cats(id=1, name='moo', weight=6.0, uid=2)
``` python
cats.drop()
cats
```
<Table cats (does not exist yet)>
Alternatively, you can create a table from a class. If it’s not already
a dataclass, it will be converted into one. In either case, the
dataclass will be created (or modified) so that `None` can be passed to
any field (this is needed to support fields such as automatic row ids).
``` python
class Cat: id:int; name:str; weight:float; uid:int
```
``` python
cats = db.create(Cat)
```
``` python
hl_md(cats.schema, 'sql')
```
``` sql
CREATE TABLE [cat] (
[id] INTEGER PRIMARY KEY,
[name] TEXT,
[weight] FLOAT,
[uid] INTEGER
)
```
``` python
cat = Cat(name='咪咪', weight=9)
cats.insert(cat)
```
Cat(id=1, name='咪咪', weight=9.0, uid=None)
``` python
cats.drop()
```
## Manipulating data
We try to make the following methods as flexible as possible. Wherever
possible, they support Python dictionaries, dataclasses, and classes.
### .insert()
Creates a record. In the name of flexibility, we test that dictionaries,
dataclasses, and classes all work. Returns an instance of the updated
record.
Insert using a dictionary.
``` python
cats.insert({'name': 'Rex', 'weight': 12.2})
```
Cat(id=1, name='Rex', weight=12.2, uid=UNSET)
Insert using a dataclass.
``` python
CatDC = cats.dataclass()
cats.insert(CatDC(name='Tom', weight=10.2))
```
Cat(id=2, name='Tom', weight=10.2)
Insert using a standard Python class
``` python
cat = cats.insert(Cat(name='Jerry', weight=5.2))
```
### .update()
Updates a record using a Python dict, dataclasses, and classes all work
and returns an instance of the updated record.
Updating from a Python dict:
``` python
cats.update(dict(id=cat.id, name='Jerry', weight=6.2))
```
Cat(id=3, name='Jerry', weight=6.2)
Updating from a dataclass:
``` python
cats.update(CatDC(id=cat.id, name='Jerry', weight=6.3))
```
Cat(id=3, name='Jerry', weight=6.3)
Updating using a class:
``` python
cats.update(Cat(id=cat.id, name='Jerry', weight=5.7))
```
Cat(id=3, name='Jerry', weight=5.7)
### .delete()
Removing data is done by providing the primary key value of the record.
``` python
# Farewell Jerry!
cats.delete(cat.id)
```
<Table cat (id, name, weight)>
### Importing CSV/TSV/etc
You can pass a file name, string, bytes, or open file handle to
`import_file` to import a CSV:
``` python
db = Database(":memory:")
csv_data = """id,name,age
1,Alice,30
2,Bob,25
3,Charlie,35"""
table = db.import_file("people", csv_data)
table()
```
[{'id': 1, 'name': 'Alice', 'age': 30},
{'id': 2, 'name': 'Bob', 'age': 25},
{'id': 3, 'name': 'Charlie', 'age': 35}]
## Diagrams
If you have [graphviz](https://pypi.org/project/graphviz/) installed,
you can create database diagrams:
``` python
diagram(db.tables)
```
![](index_files/figure-commonmark/cell-45-output-1.svg)
Pass a subset of tables to just diagram those. You can also adjust the
size and aspect ratio.
``` python
diagram(db.t['Artist','Album','Track','Genre','MediaType'], size=8, ratio=0.4)
```
![](index_files/figure-commonmark/cell-46-output-1.svg)
Raw data
{
"_id": null,
"home_page": "https://github.com/AnswerDotAI/fastlite",
"name": "fastlite",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "nbdev jupyter notebook python sqlite sql",
"author": "Jeremy Howard",
"author_email": "info@fast.ai",
"download_url": "https://files.pythonhosted.org/packages/92/86/c6392b7d6fbfa3f5eb22054645ec7be550a21bfb00ce9586ba2bc18e12d2/fastlite-0.0.13.tar.gz",
"platform": null,
"description": "# fastlite\n\n\n<!-- WARNING: THIS FILE WAS AUTOGENERATED! DO NOT EDIT! -->\n\n`fastlite` provides some little quality-of-life improvements for\ninteractive use of the wonderful\n[sqlite-utils](https://sqlite-utils.datasette.io/) library. It\u2019s likely\nto be particularly of interest to folks using Jupyter.\n\n## Install\n\n pip install fastlite\n\n## Overview\n\n``` python\nfrom fastlite import *\nfrom fastcore.utils import *\nfrom fastcore.net import urlsave\n```\n\nWe demonstrate `fastlite`\u2018s features here using the \u2019chinook\u2019 sample\ndatabase.\n\n``` python\nurl = 'https://github.com/lerocha/chinook-database/raw/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite'\npath = Path('chinook.sqlite')\nif not path.exists(): urlsave(url, path)\n\ndb = database(\"chinook.sqlite\")\n```\n\nDatabases have a `t` property that lists all tables:\n\n``` python\ndt = db.t\ndt\n```\n\n Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track\n\nYou can use this to grab a single table\u2026:\n\n``` python\nartist = dt.artists\nartist\n```\n\n <Table artists (does not exist yet)>\n\n``` python\nartist = dt.Artist\nartist\n```\n\n <Table Artist (ArtistId, Name)>\n\n\u2026or multiple tables at once:\n\n``` python\ndt['Artist','Album','Track','Genre','MediaType']\n```\n\n [<Table Artist (ArtistId, Name)>,\n <Table Album (AlbumId, Title, ArtistId)>,\n <Table Track (TrackId, Name, AlbumId, MediaTypeId, GenreId, Composer, Milliseconds, Bytes, UnitPrice)>,\n <Table Genre (GenreId, Name)>,\n <Table MediaType (MediaTypeId, Name)>]\n\nIt also provides auto-complete in Jupyter, IPython, and nearly any other\ninteractive Python environment:\n\n<img src=\"index_files/figure-commonmark/cell-16-1-image.png\"\nwidth=\"180\" />\n\nYou can check if a table is in the database already:\n\n``` python\n'Artist' in dt\n```\n\n True\n\nColumn work in a similar way to tables, using the `c` property:\n\n``` python\nac = artist.c\nac\n```\n\n ArtistId, Name\n\nAuto-complete works for columns too:\n\n<img src=\"index_files/figure-commonmark/cell-21-1-image.png\"\nwidth=\"140\" />\n\nColumns, tables, and view stringify in a format suitable for including\nin SQL statements. That means you can use auto-complete in f-strings.\n\n``` python\nqry = f\"select * from {artist} where {ac.Name} like 'AC/%'\"\nprint(qry)\n```\n\n select * from \"Artist\" where \"Artist\".\"Name\" like 'AC/%'\n\nYou can view the results of a select query using `q`:\n\n``` python\ndb.q(qry)\n```\n\n [{'ArtistId': 1, 'Name': 'AC/DC'}]\n\nViews can be accessed through the `v` property:\n\n``` python\nalbum = dt.Album\n\nacca_sql = f\"\"\"select {album}.*\nfrom {album} join {artist} using (ArtistId)\nwhere {ac.Name} like 'AC/%'\"\"\"\n\ndb.create_view(\"AccaDaccaAlbums\", acca_sql, replace=True)\nacca_dacca = db.q(f\"select * from {db.v.AccaDaccaAlbums}\")\nacca_dacca\n```\n\n [{'AlbumId': 1,\n 'Title': 'For Those About To Rock We Salute You',\n 'ArtistId': 1},\n {'AlbumId': 4, 'Title': 'Let There Be Rock', 'ArtistId': 1}]\n\n## Dataclass support\n\nA `dataclass` type with the names, types, and defaults of the tables is\ncreated using `dataclass()`:\n\n``` python\nalbum_dc = album.dataclass()\n```\n\nLet\u2019s try it:\n\n``` python\nalbum_obj = album_dc(**acca_dacca[0])\nalbum_obj\n```\n\n Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1)\n\nYou can get the definition of the dataclass using fastcore\u2019s\n`dataclass_src` \u2013 everything is treated as nullable, in order to handle\nauto-generated database values:\n\n``` python\nsrc = dataclass_src(album_dc)\nhl_md(src, 'python')\n```\n\n``` python\n@dataclass\nclass Album:\n AlbumId: int | None = None\n Title: str | None = None\n ArtistId: int | None = None\n```\n\nBecause `dataclass()` is dynamic, you won\u2019t get auto-complete in editors\nlike vscode \u2013 it\u2019ll only work in dynamic environments like Jupyter and\nIPython. For editor support, you can export the full set of dataclasses\nto a module, which you can then import from:\n\n``` python\ncreate_mod(db, 'db_dc')\n```\n\n``` python\nfrom db_dc import Track\nTrack()\n```\n\n Track(TrackId=None, Name=None, AlbumId=None, MediaTypeId=None, GenreId=None, Composer=None, Milliseconds=None, Bytes=None, UnitPrice=None)\n\nIndexing into a table does a query on primary key:\n\n``` python\ndt.Track[1]\n```\n\n Track(TrackId=1, Name='For Those About To Rock (We Salute You)', AlbumId=1, MediaTypeId=1, GenreId=1, Composer='Angus Young, Malcolm Young, Brian Johnson', Milliseconds=343719, Bytes=11170334, UnitPrice=0.99)\n\nThere\u2019s a shortcut to select from a table \u2013 just call it as a function.\nIf you\u2019ve previously called `dataclass()`, returned iterms will be\nconstructed using that class by default. There\u2019s lots of params you can\ncheck out, such as `limit`:\n\n``` python\nalbum(limit=2)\n```\n\n [Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1),\n Album(AlbumId=2, Title='Balls to the Wall', ArtistId=2)]\n\nPass a truthy value as `with_pk` and you\u2019ll get tuples of primary keys\nand records:\n\n``` python\nalbum(with_pk=1, limit=2)\n```\n\n [(1,\n Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1)),\n (2, Album(AlbumId=2, Title='Balls to the Wall', ArtistId=2))]\n\nIndexing also uses the dataclass by default:\n\n``` python\nalbum[5]\n```\n\n Album(AlbumId=5, Title='Big Ones', ArtistId=3)\n\nIf you set `xtra` fields, then indexing is also filtered by those. As a\nresult, for instance in this case, nothing is returned since album 5 is\nnot created by artist 1:\n\n``` python\nalbum.xtra(ArtistId=1)\n\ntry: album[5]\nexcept NotFoundError: print(\"Not found\")\n```\n\n Not found\n\nThe same filtering is done when using the table as a callable:\n\n``` python\nalbum()\n```\n\n [Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1),\n Album(AlbumId=4, Title='Let There Be Rock', ArtistId=1)]\n\n## Core design\n\nThe following methods accept `**kwargs`, passing them along to the first\n`dict` param:\n\n- `create`\n- `transform`\n- `transform_sql`\n- `update`\n- `insert`\n- `upsert`\n- `lookup`\n\nWe can access a table that doesn\u2019t actually exist yet:\n\n``` python\ncats = dt.cats\ncats\n```\n\n <Table cats (does not exist yet)>\n\nWe can use keyword arguments to now create that table:\n\n``` python\ncats.create(id=int, name=str, weight=float, uid=int, pk='id')\nhl_md(cats.schema, 'sql')\n```\n\n``` sql\nCREATE TABLE [cats] (\n [id] INTEGER PRIMARY KEY,\n [name] TEXT,\n [weight] FLOAT,\n [uid] INTEGER\n)\n```\n\nIt we set `xtra` then the additional fields are used for `insert`,\n`update`, and `delete`:\n\n``` python\ncats.xtra(uid=2)\ncat = cats.insert(name='meow', weight=6)\n```\n\nThe inserted row is returned, including the xtra \u2018uid\u2019 field.\n\n``` python\ncat\n```\n\n {'id': 1, 'name': 'meow', 'weight': 6.0, 'uid': 2}\n\nUsing `**` in `update` here doesn\u2019t actually achieve anything, since we\ncan just pass a `dict` directly \u2013 it\u2019s just to show that it works:\n\n``` python\ncat['name'] = \"moo\"\ncat['uid'] = 1\ncats.update(**cat)\ncats()\n```\n\n [{'id': 1, 'name': 'moo', 'weight': 6.0, 'uid': 2}]\n\nAttempts to update or insert with xtra fields are ignored.\n\nAn error is raised if there\u2019s an attempt to update a record not matching\n`xtra` fields:\n\n``` python\ncats.xtra(uid=1)\ntry: cats.update(**cat)\nexcept NotFoundError: print(\"Not found\")\n```\n\n Not found\n\nThis all also works with dataclasses:\n\n``` python\ncats.xtra(uid=2)\ncats.dataclass()\ncat = cats[1]\ncat\n```\n\n Cats(id=1, name='moo', weight=6.0, uid=2)\n\n``` python\ncats.drop()\ncats\n```\n\n <Table cats (does not exist yet)>\n\nAlternatively, you can create a table from a class. If it\u2019s not already\na dataclass, it will be converted into one. In either case, the\ndataclass will be created (or modified) so that `None` can be passed to\nany field (this is needed to support fields such as automatic row ids).\n\n``` python\nclass Cat: id:int; name:str; weight:float; uid:int\n```\n\n``` python\ncats = db.create(Cat)\n```\n\n``` python\nhl_md(cats.schema, 'sql')\n```\n\n``` sql\nCREATE TABLE [cat] (\n [id] INTEGER PRIMARY KEY,\n [name] TEXT,\n [weight] FLOAT,\n [uid] INTEGER\n)\n```\n\n``` python\ncat = Cat(name='\u54aa\u54aa', weight=9)\ncats.insert(cat)\n```\n\n Cat(id=1, name='\u54aa\u54aa', weight=9.0, uid=None)\n\n``` python\ncats.drop()\n```\n\n## Manipulating data\n\nWe try to make the following methods as flexible as possible. Wherever\npossible, they support Python dictionaries, dataclasses, and classes.\n\n### .insert()\n\nCreates a record. In the name of flexibility, we test that dictionaries,\ndataclasses, and classes all work. Returns an instance of the updated\nrecord.\n\nInsert using a dictionary.\n\n``` python\ncats.insert({'name': 'Rex', 'weight': 12.2})\n```\n\n Cat(id=1, name='Rex', weight=12.2, uid=UNSET)\n\nInsert using a dataclass.\n\n``` python\nCatDC = cats.dataclass()\ncats.insert(CatDC(name='Tom', weight=10.2))\n```\n\n Cat(id=2, name='Tom', weight=10.2)\n\nInsert using a standard Python class\n\n``` python\ncat = cats.insert(Cat(name='Jerry', weight=5.2))\n```\n\n### .update()\n\nUpdates a record using a Python dict, dataclasses, and classes all work\nand returns an instance of the updated record.\n\nUpdating from a Python dict:\n\n``` python\ncats.update(dict(id=cat.id, name='Jerry', weight=6.2))\n```\n\n Cat(id=3, name='Jerry', weight=6.2)\n\nUpdating from a dataclass:\n\n``` python\ncats.update(CatDC(id=cat.id, name='Jerry', weight=6.3))\n```\n\n Cat(id=3, name='Jerry', weight=6.3)\n\nUpdating using a class:\n\n``` python\ncats.update(Cat(id=cat.id, name='Jerry', weight=5.7))\n```\n\n Cat(id=3, name='Jerry', weight=5.7)\n\n### .delete()\n\nRemoving data is done by providing the primary key value of the record.\n\n``` python\n# Farewell Jerry!\ncats.delete(cat.id)\n```\n\n <Table cat (id, name, weight)>\n\n### Importing CSV/TSV/etc\n\nYou can pass a file name, string, bytes, or open file handle to\n`import_file` to import a CSV:\n\n``` python\ndb = Database(\":memory:\")\ncsv_data = \"\"\"id,name,age\n1,Alice,30\n2,Bob,25\n3,Charlie,35\"\"\"\n\ntable = db.import_file(\"people\", csv_data)\ntable()\n```\n\n [{'id': 1, 'name': 'Alice', 'age': 30},\n {'id': 2, 'name': 'Bob', 'age': 25},\n {'id': 3, 'name': 'Charlie', 'age': 35}]\n\n## Diagrams\n\nIf you have [graphviz](https://pypi.org/project/graphviz/) installed,\nyou can create database diagrams:\n\n``` python\ndiagram(db.tables)\n```\n\n![](index_files/figure-commonmark/cell-45-output-1.svg)\n\nPass a subset of tables to just diagram those. You can also adjust the\nsize and aspect ratio.\n\n``` python\ndiagram(db.t['Artist','Album','Track','Genre','MediaType'], size=8, ratio=0.4)\n```\n\n![](index_files/figure-commonmark/cell-46-output-1.svg)\n",
"bugtrack_url": null,
"license": "Apache Software License 2.0",
"summary": "A bit of extra usability for sqlite",
"version": "0.0.13",
"project_urls": {
"Homepage": "https://github.com/AnswerDotAI/fastlite"
},
"split_keywords": [
"nbdev",
"jupyter",
"notebook",
"python",
"sqlite",
"sql"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6cb40d9e28d1de34378033ce6305f531c2e9dd4adc00915d57f83d1acfa805d7",
"md5": "dc5a5467ee453ee39d337f64b1a2a080",
"sha256": "8a8fac42ff71cdebd03272a8a2d8564c266dda1510b8d3e2dfaeae8a69c3e834"
},
"downloads": -1,
"filename": "fastlite-0.0.13-py3-none-any.whl",
"has_sig": false,
"md5_digest": "dc5a5467ee453ee39d337f64b1a2a080",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 16464,
"upload_time": "2024-10-22T07:52:38",
"upload_time_iso_8601": "2024-10-22T07:52:38.508336Z",
"url": "https://files.pythonhosted.org/packages/6c/b4/0d9e28d1de34378033ce6305f531c2e9dd4adc00915d57f83d1acfa805d7/fastlite-0.0.13-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "9286c6392b7d6fbfa3f5eb22054645ec7be550a21bfb00ce9586ba2bc18e12d2",
"md5": "5b0d2f5fe151140b3c22923870d2fa5c",
"sha256": "e3039dd3ef144953691ea93ed902e46885a7d904feae92a11c835196693ad370"
},
"downloads": -1,
"filename": "fastlite-0.0.13.tar.gz",
"has_sig": false,
"md5_digest": "5b0d2f5fe151140b3c22923870d2fa5c",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 20596,
"upload_time": "2024-10-22T07:52:40",
"upload_time_iso_8601": "2024-10-22T07:52:40.035664Z",
"url": "https://files.pythonhosted.org/packages/92/86/c6392b7d6fbfa3f5eb22054645ec7be550a21bfb00ce9586ba2bc18e12d2/fastlite-0.0.13.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-22 07:52:40",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "AnswerDotAI",
"github_project": "fastlite",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "fastlite"
}