diff --git a/fastlite/_modidx.py b/fastlite/_modidx.py
index 6c0844f..f25885c 100644
--- a/fastlite/_modidx.py
+++ b/fastlite/_modidx.py
@@ -12,7 +12,6 @@
'fastlite.core.Table.__str__': ('core.html#table.__str__', 'fastlite/core.py'),
'fastlite.core.Table.c': ('core.html#table.c', 'fastlite/core.py'),
'fastlite.core.Table.dataclass': ('core.html#table.dataclass', 'fastlite/core.py'),
- 'fastlite.core.Table.get': ('core.html#table.get', 'fastlite/core.py'),
'fastlite.core.View.__call__': ('core.html#view.__call__', 'fastlite/core.py'),
'fastlite.core.View.__str__': ('core.html#view.__str__', 'fastlite/core.py'),
'fastlite.core.View.c': ('core.html#view.c', 'fastlite/core.py'),
diff --git a/fastlite/core.py b/fastlite/core.py
index e8b4f55..cc55b05 100644
--- a/fastlite/core.py
+++ b/fastlite/core.py
@@ -114,21 +114,14 @@ def __call__(
else: res = (self.cls(**o) for o in res)
return list(res)
-# %% ../nbs/00_core.ipynb 39
-@patch
-def get(self:Table, pk_values: list|tuple|str|int, as_cls:bool=True)->Any:
- res = self._orig_get(pk_values=pk_values)
- if as_cls and hasattr(self,'cls'): res = self.cls(**res)
- return res
-
-# %% ../nbs/00_core.ipynb 45
+# %% ../nbs/00_core.ipynb 44
class _ViewsGetter(_Getter):
def __dir__(self): return self.db.view_names()
@patch(as_prop=True)
def v(self:Database): return _ViewsGetter(self)
-# %% ../nbs/00_core.ipynb 51
+# %% ../nbs/00_core.ipynb 50
def _edge(tbl):
return "\n".join(f"{fk.table}:{fk.column} -> {fk.other_table}:{fk.other_column};"
for fk in tbl.foreign_keys)
@@ -146,7 +139,7 @@ def _tnode(tbl):
"""
return f"{tbl.name} [label=<{res}>];\n"
-# %% ../nbs/00_core.ipynb 52
+# %% ../nbs/00_core.ipynb 51
def diagram(tbls, ratio=0.7, size="10", neato=False, render=True):
layout = "\nlayout=neato;\noverlap=prism;\noverlap_scaling=0.5;""" if neato else ""
edges = "\n".join(map(_edge, tbls))
diff --git a/fastlite/kw.py b/fastlite/kw.py
index b0d8660..5357a18 100644
--- a/fastlite/kw.py
+++ b/fastlite/kw.py
@@ -3,20 +3,43 @@
from fastcore.utils import *
import sqlite_utils
from sqlite_utils import Database
-from sqlite_utils.db import Table,DEFAULT,ForeignKeysType,Default,Queryable
+from sqlite_utils.db import Table,DEFAULT,ForeignKeysType,Default,Queryable,NotFoundError
+
+@patch
+def xtra(self:Table, **kwargs):
+ "Set `xtra_id`"
+ self.xtra_id = kwargs
+
+@patch
+def get(self:Table, pk_values: list|tuple|str|int, as_cls:bool=True)->Any:
+ if not isinstance(pk_values, (list, tuple)): pk_values = [pk_values]
+ last_pk = pk_values[0] if len(self.pks) == 1 else pk_values
+ xtra = getattr(self, 'xtra_id', {})
+ vals = pk_values + list(xtra.values())
+ pks = self.pks + list(xtra.keys())
+ if len(pks) != len(vals):
+ raise NotFoundError( "Need {} primary key value{}".format( len(pks), "" if len(pks) == 1 else "s"))
+
+ wheres = ["[{}] = ?".format(pk_name) for pk_name in pks]
+ rows = self.rows_where(" and ".join(wheres), vals)
+ try: row = list(rows)[0]
+ except IndexError: raise NotFoundError
+ self.last_pk = last_pk
+ if as_cls and hasattr(self,'cls'): row = self.cls(**row)
+ return row
@patch
def create(
self:Table,
columns: Dict[str, Any]=None,
- pk: Optional[Any] = None,
+ pk: Any|None = None,
foreign_keys: Union[Iterable[Union[str, sqlite_utils.db.ForeignKey, Tuple[str, str], Tuple[str, str, str], Tuple[str, str, str, str]]], List[Union[str, sqlite_utils.db.ForeignKey, Tuple[str, str], Tuple[str, str, str], Tuple[str, str, str, str]]], NoneType] = None,
- column_order: Optional[List[str]] = None,
- not_null: Optional[Iterable[str]] = None,
- defaults: Optional[Dict[str, Any]] = None,
- hash_id: Optional[str] = None,
- hash_id_columns: Optional[Iterable[str]] = None,
+ column_order: List[str]|None = None,
+ not_null: Iterable[str]|None = None,
+ defaults: Dict[str, Any]|None = None,
+ hash_id: str|None = None,
+ hash_id_columns: Iterable[str]|None = None,
extracts: Union[Dict[str, str], List[str], NoneType] = None,
if_not_exists: bool = False,
replace: bool = False,
@@ -34,17 +57,17 @@ def create(
@patch
def transform(
self:Table, *,
- types: Optional[dict] = None,
- rename: Optional[dict] = None,
- drop: Optional[Iterable] = None,
- pk: Optional[Any] = DEFAULT,
- not_null: Optional[Iterable[str]] = None,
- defaults: Optional[Dict[str, Any]] = None,
- drop_foreign_keys: Optional[Iterable[str]] = None,
- add_foreign_keys: Optional[ForeignKeysType] = None,
- foreign_keys: Optional[ForeignKeysType] = None,
- column_order: Optional[List[str]] = None,
- keep_table: Optional[str] = None,
+ types: dict|None = None,
+ rename: dict|None = None,
+ drop: Iterable|None = None,
+ pk: Any|None = DEFAULT,
+ not_null: Iterable[str]|None = None,
+ defaults: Dict[str, Any]|None = None,
+ drop_foreign_keys: Iterable[str]|None = None,
+ add_foreign_keys: ForeignKeysType|None = None,
+ foreign_keys: ForeignKeysType|None = None,
+ column_order: List[str]|None = None,
+ keep_table: str|None = None,
**kwargs) -> Table:
if not types: types={}
types = {**types, **kwargs}
@@ -56,17 +79,17 @@ def transform(
@patch
def transform_sql(
self:Table, *,
- types: Optional[dict] = None,
- rename: Optional[dict] = None,
- drop: Optional[Iterable] = None,
- pk: Optional[Any] = DEFAULT,
- not_null: Optional[Iterable[str]] = None,
- defaults: Optional[Dict[str, Any]] = None,
- drop_foreign_keys: Optional[Iterable[str]] = None,
- add_foreign_keys: Optional[ForeignKeysType] = None,
- foreign_keys: Optional[ForeignKeysType] = None,
- column_order: Optional[List[str]] = None,
- keep_table: Optional[str] = None,
+ types: dict|None = None,
+ rename: dict|None = None,
+ drop: Iterable|None = None,
+ pk: Any|None = DEFAULT,
+ not_null: Iterable[str]|None = None,
+ defaults: Dict[str, Any]|None = None,
+ drop_foreign_keys: Iterable[str]|None = None,
+ add_foreign_keys: ForeignKeysType|None = None,
+ foreign_keys: ForeignKeysType|None = None,
+ column_order: List[str]|None = None,
+ keep_table: str|None = None,
**kwargs) -> List[str]:
if not types: types={}
types = {**types, **kwargs}
@@ -81,30 +104,61 @@ def update(self:Table, updates: dict|None=None, pk_values: list|tuple|str|int|fl
alter: bool=False, conversions: dict|None=None, **kwargs):
if not updates: updates={}
if is_dataclass(updates): updates = asdict(updates)
- updates = {**updates, **kwargs}
+ xtra = getattr(self, 'xtra_id', {})
+ updates = {**updates, **kwargs, **xtra}
if not pk_values: pk_values = [updates[o] for o in self.pks]
self._orig_update(pk_values, updates=updates, alter=alter, conversions=conversions)
return self.get(self.last_pk)
+@patch
+def insert_all(
+ self:Table,
+ records: Dict[str, Any]=None, pk=DEFAULT, foreign_keys=DEFAULT,
+ column_order: Union[List[str], Default, None] = DEFAULT,
+ not_null: Union[Iterable[str], Default, None] = DEFAULT,
+ defaults: Union[Dict[str, Any], Default, None] = DEFAULT,
+ batch_size=DEFAULT,
+ hash_id: Union[str, Default, None] = DEFAULT,
+ hash_id_columns: Union[Iterable[str], Default, None] = DEFAULT,
+ alter: Union[bool, Default, None] = DEFAULT,
+ ignore: Union[bool, Default, None] = DEFAULT,
+ replace: Union[bool, Default, None] = DEFAULT,
+ truncate=False,
+ extracts: Union[Dict[str, str], List[str], Default, None] = DEFAULT,
+ conversions: Union[Dict[str, str], Default, None] = DEFAULT,
+ columns: Union[Dict[str, Any], Default, None] = DEFAULT,
+ strict: Union[bool, Default, None] = DEFAULT,
+ upsert:bool=False, analyze:bool=False,
+ **kwargs) -> Table:
+ xtra = getattr(self,'xtra_id',{})
+ records = [asdict(o) if is_dataclass(o) else o for o in records]
+ records = [{**o, **xtra} for o in records]
+ return self._orig_insert_all(
+ records=records, pk=pk, foreign_keys=foreign_keys, column_order=column_order, not_null=not_null,
+ defaults=defaults, batch_size=batch_size, hash_id=hash_id, hash_id_columns=hash_id_columns, alter=alter,
+ ignore=ignore, replace=replace, truncate=truncate, extracts=extracts, conversions=conversions,
+ columns=columns, strict=strict, upsert=upsert, analyze=analyze)
+
+
@patch
def insert(
self:Table,
record: Dict[str, Any]=None,
pk=DEFAULT,
foreign_keys=DEFAULT,
- column_order: Optional[Union[List[str], Default]] = DEFAULT,
- not_null: Optional[Union[Iterable[str], Default]] = DEFAULT,
- defaults: Optional[Union[Dict[str, Any], Default]] = DEFAULT,
- hash_id: Optional[Union[str, Default]] = DEFAULT,
- hash_id_columns: Optional[Union[Iterable[str], Default]] = DEFAULT,
- alter: Optional[Union[bool, Default]] = DEFAULT,
- ignore: Optional[Union[bool, Default]] = DEFAULT,
- replace: Optional[Union[bool, Default]] = DEFAULT,
- extracts: Optional[Union[Dict[str, str], List[str], Default]] = DEFAULT,
- conversions: Optional[Union[Dict[str, str], Default]] = DEFAULT,
- columns: Optional[Union[Dict[str, Any], Default]] = DEFAULT,
- strict: Optional[Union[bool, Default]] = DEFAULT,
+ column_order: Union[List[str], Default, None] = DEFAULT,
+ not_null: Union[Iterable[str], Default, None] = DEFAULT,
+ defaults: Union[Dict[str, Any], Default, None] = DEFAULT,
+ hash_id: Union[str, Default, None] = DEFAULT,
+ hash_id_columns: Union[Iterable[str], Default, None] = DEFAULT,
+ alter: Union[bool, Default, None] = DEFAULT,
+ ignore: Union[bool, Default, None] = DEFAULT,
+ replace: Union[bool, Default, None] = DEFAULT,
+ extracts: Union[Dict[str, str], List[str], Default, None] = DEFAULT,
+ conversions: Union[Dict[str, str], Default, None] = DEFAULT,
+ columns: Union[Dict[str, Any], Default, None] = DEFAULT,
+ strict: Union[bool, Default, None] = DEFAULT,
**kwargs) -> Table:
if not record: record={}
if is_dataclass(record): record = asdict(record)
@@ -122,16 +176,16 @@ def upsert(
record:Any=None,
pk=DEFAULT,
foreign_keys=DEFAULT,
- column_order: Optional[Union[List[str], Default]] = DEFAULT,
- not_null: Optional[Union[Iterable[str], Default]] = DEFAULT,
- defaults: Optional[Union[Dict[str, Any], Default]] = DEFAULT,
- hash_id: Optional[Union[str, Default]] = DEFAULT,
- hash_id_columns: Optional[Union[Iterable[str], Default]] = DEFAULT,
- alter: Optional[Union[bool, Default]] = DEFAULT,
- extracts: Optional[Union[Dict[str, str], List[str], Default]] = DEFAULT,
- conversions: Optional[Union[Dict[str, str], Default]] = DEFAULT,
- columns: Optional[Union[Dict[str, Any], Default]] = DEFAULT,
- strict: Optional[Union[bool, Default]] = DEFAULT,
+ column_order: Union[List[str], Default, None] = DEFAULT,
+ not_null: Union[Iterable[str], Default, None] = DEFAULT,
+ defaults: Union[Dict[str, Any], Default, None] = DEFAULT,
+ hash_id: Union[str, Default]|None = DEFAULT,
+ hash_id_columns: Union[Iterable[str], Default, None] = DEFAULT,
+ alter: Union[bool, Default]|None = DEFAULT,
+ extracts: Union[Dict[str, str], List[str], Default, None] = DEFAULT,
+ conversions: Union[Dict[str, str], Default, None] = DEFAULT,
+ columns: Union[Dict[str, Any], Default, None] = DEFAULT,
+ strict: Union[bool, Default]|None = DEFAULT,
**kwargs) -> Table:
if pk==DEFAULT:
assert len(self.pks)==1
@@ -150,16 +204,16 @@ def upsert(
def lookup(
self:Table,
lookup_values: Dict[str, Any],
- extra_values: Optional[Dict[str, Any]] = None,
- pk: Optional[str] = "id",
- foreign_keys: Optional[ForeignKeysType] = None,
- column_order: Optional[List[str]] = None,
- not_null: Optional[Iterable[str]] = None,
- defaults: Optional[Dict[str, Any]] = None,
- extracts: Optional[Union[Dict[str, str], List[str]]] = None,
- conversions: Optional[Dict[str, str]] = None,
- columns: Optional[Dict[str, Any]] = None,
- strict: Optional[bool] = False,
+ extra_values: Dict[str, Any]|None = None,
+ pk: str|None = "id",
+ foreign_keys: ForeignKeysType|None = None,
+ column_order: List[str]|None = None,
+ not_null: Iterable[str]|None = None,
+ defaults: Dict[str, Any]|None = None,
+ extracts: Union[Dict[str, str], List[str], None] = None,
+ conversions: Dict[str, str]|None = None,
+ columns: Dict[str, Any]|None = None,
+ strict: bool|None = False,
**kwargs):
if not lookup_values: lookup_values={}
lookup_values = {**lookup_values, **kwargs}
diff --git a/nbs/00_core.ipynb b/nbs/00_core.ipynb
index 0b91a56..dd56e04 100644
--- a/nbs/00_core.ipynb
+++ b/nbs/00_core.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@@ -27,7 +27,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
@@ -48,7 +48,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
@@ -57,7 +57,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
@@ -66,7 +66,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
@@ -100,16 +100,16 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track"
+ "Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track, cats"
]
},
- "execution_count": null,
+ "execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
@@ -121,7 +121,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 7,
"metadata": {},
"outputs": [
{
@@ -130,7 +130,7 @@
"
"
]
},
- "execution_count": null,
+ "execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@@ -149,7 +149,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 8,
"metadata": {},
"outputs": [
{
@@ -158,7 +158,7 @@
"[, ]"
]
},
- "execution_count": null,
+ "execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -169,7 +169,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
@@ -180,7 +180,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
@@ -217,7 +217,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 11,
"metadata": {},
"outputs": [
{
@@ -226,7 +226,7 @@
"ArtistId, Name"
]
},
- "execution_count": null,
+ "execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
@@ -245,7 +245,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 12,
"metadata": {},
"outputs": [
{
@@ -262,7 +262,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 13,
"metadata": {},
"outputs": [],
"source": [
@@ -283,7 +283,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 14,
"metadata": {},
"outputs": [
{
@@ -300,7 +300,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
@@ -318,7 +318,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 16,
"metadata": {},
"outputs": [],
"source": [
@@ -337,7 +337,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 17,
"metadata": {},
"outputs": [
{
@@ -346,7 +346,7 @@
"[{'ArtistId': 1, 'Name': 'AC/DC'}]"
]
},
- "execution_count": null,
+ "execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
@@ -358,7 +358,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
@@ -377,7 +377,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 19,
"metadata": {},
"outputs": [
{
@@ -386,7 +386,7 @@
"Artist(ArtistId=1, Name='AC/DC')"
]
},
- "execution_count": null,
+ "execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
@@ -406,7 +406,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 20,
"metadata": {},
"outputs": [
{
@@ -424,7 +424,7 @@
""
]
},
- "execution_count": null,
+ "execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
@@ -436,7 +436,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
@@ -448,7 +448,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 22,
"metadata": {},
"outputs": [],
"source": [
@@ -465,7 +465,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
@@ -474,7 +474,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 24,
"metadata": {},
"outputs": [
{
@@ -483,7 +483,7 @@
"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)"
]
},
- "execution_count": null,
+ "execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
@@ -496,7 +496,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 25,
"metadata": {},
"outputs": [],
"source": [
@@ -525,16 +525,16 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "[Artist_cls(ArtistId=1, Name='AC/DC'), Artist_cls(ArtistId=2, Name='Accept')]"
+ "[Artist(ArtistId=1, Name='AC/DC'), Artist(ArtistId=2, Name='Accept')]"
]
},
- "execution_count": null,
+ "execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
@@ -552,17 +552,16 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "[(1, Artist_cls(ArtistId=1, Name='AC/DC')),\n",
- " (2, Artist_cls(ArtistId=2, Name='Accept'))]"
+ "[(1, Artist(ArtistId=1, Name='AC/DC')), (2, Artist(ArtistId=2, Name='Accept'))]"
]
},
- "execution_count": null,
+ "execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
@@ -573,30 +572,16 @@
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {},
- "outputs": [],
- "source": [
- "#| exports\n",
- "@patch\n",
- "def get(self:Table, pk_values: list|tuple|str|int, as_cls:bool=True)->Any:\n",
- " res = self._orig_get(pk_values=pk_values)\n",
- " if as_cls and hasattr(self,'cls'): res = self.cls(**res)\n",
- " return res"
- ]
- },
- {
- "cell_type": "code",
- "execution_count": null,
+ "execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "Artist_cls(ArtistId=1, Name='AC/DC')"
+ "{'ArtistId': 1, 'Name': 'AC/DC'}"
]
},
- "execution_count": null,
+ "execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
@@ -607,7 +592,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
@@ -620,7 +605,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 30,
"metadata": {},
"outputs": [
{
@@ -636,7 +621,7 @@
""
]
},
- "execution_count": null,
+ "execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
@@ -647,7 +632,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 31,
"metadata": {},
"outputs": [
{
@@ -659,7 +644,7 @@
" {'AlbumId': 4, 'Title': 'Let There Be Rock', 'ArtistId': 1}]"
]
},
- "execution_count": null,
+ "execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
@@ -670,16 +655,16 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- ">"
+ ">"
]
},
- "execution_count": null,
+ "execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
@@ -690,7 +675,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
@@ -704,7 +689,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 34,
"metadata": {},
"outputs": [
{
@@ -713,7 +698,7 @@
"AccaDaccaAlbums"
]
},
- "execution_count": null,
+ "execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
@@ -725,7 +710,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 35,
"metadata": {},
"outputs": [
{
@@ -737,7 +722,7 @@
" {'AlbumId': 4, 'Title': 'Let There Be Rock', 'ArtistId': 1}]"
]
},
- "execution_count": null,
+ "execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
@@ -1170,7 +1155,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
@@ -1188,9 +1173,21 @@
],
"metadata": {
"kernelspec": {
- "display_name": "python3",
+ "display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.8"
}
},
"nbformat": 4,
diff --git a/nbs/index.ipynb b/nbs/index.ipynb
index cb9e727..fea1fb7 100644
--- a/nbs/index.ipynb
+++ b/nbs/index.ipynb
@@ -43,7 +43,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
@@ -62,7 +62,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
@@ -82,7 +82,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
"outputs": [
{
@@ -91,7 +91,7 @@
"Album, Artist, Customer, Employee, Genre, Invoice, InvoiceLine, MediaType, Playlist, PlaylistTrack, Track"
]
},
- "execution_count": null,
+ "execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
@@ -110,7 +110,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
"outputs": [
{
@@ -119,7 +119,7 @@
""
]
},
- "execution_count": null,
+ "execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
@@ -129,6 +129,321 @@
"artist"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[{'ArtistId': 1, 'Name': 'AC/DC'},\n",
+ " {'ArtistId': 2, 'Name': 'Accept'},\n",
+ " {'ArtistId': 3, 'Name': 'Aerosmith'},\n",
+ " {'ArtistId': 4, 'Name': 'Alanis Morissette'},\n",
+ " {'ArtistId': 5, 'Name': 'Alice In Chains'},\n",
+ " {'ArtistId': 6, 'Name': 'Antônio Carlos Jobim'},\n",
+ " {'ArtistId': 7, 'Name': 'Apocalyptica'},\n",
+ " {'ArtistId': 8, 'Name': 'Audioslave'},\n",
+ " {'ArtistId': 9, 'Name': 'BackBeat'},\n",
+ " {'ArtistId': 10, 'Name': 'Billy Cobham'},\n",
+ " {'ArtistId': 11, 'Name': 'Black Label Society'},\n",
+ " {'ArtistId': 12, 'Name': 'Black Sabbath'},\n",
+ " {'ArtistId': 13, 'Name': 'Body Count'},\n",
+ " {'ArtistId': 14, 'Name': 'Bruce Dickinson'},\n",
+ " {'ArtistId': 15, 'Name': 'Buddy Guy'},\n",
+ " {'ArtistId': 16, 'Name': 'Caetano Veloso'},\n",
+ " {'ArtistId': 17, 'Name': 'Chico Buarque'},\n",
+ " {'ArtistId': 18, 'Name': 'Chico Science & Nação Zumbi'},\n",
+ " {'ArtistId': 19, 'Name': 'Cidade Negra'},\n",
+ " {'ArtistId': 20, 'Name': 'Cláudio Zoli'},\n",
+ " {'ArtistId': 21, 'Name': 'Various Artists'},\n",
+ " {'ArtistId': 22, 'Name': 'Led Zeppelin'},\n",
+ " {'ArtistId': 23, 'Name': 'Frank Zappa & Captain Beefheart'},\n",
+ " {'ArtistId': 24, 'Name': 'Marcos Valle'},\n",
+ " {'ArtistId': 25, 'Name': 'Milton Nascimento & Bebeto'},\n",
+ " {'ArtistId': 26, 'Name': 'Azymuth'},\n",
+ " {'ArtistId': 27, 'Name': 'Gilberto Gil'},\n",
+ " {'ArtistId': 28, 'Name': 'João Gilberto'},\n",
+ " {'ArtistId': 29, 'Name': 'Bebel Gilberto'},\n",
+ " {'ArtistId': 30, 'Name': 'Jorge Vercilo'},\n",
+ " {'ArtistId': 31, 'Name': 'Baby Consuelo'},\n",
+ " {'ArtistId': 32, 'Name': 'Ney Matogrosso'},\n",
+ " {'ArtistId': 33, 'Name': 'Luiz Melodia'},\n",
+ " {'ArtistId': 34, 'Name': 'Nando Reis'},\n",
+ " {'ArtistId': 35, 'Name': 'Pedro Luís & A Parede'},\n",
+ " {'ArtistId': 36, 'Name': 'O Rappa'},\n",
+ " {'ArtistId': 37, 'Name': 'Ed Motta'},\n",
+ " {'ArtistId': 38, 'Name': 'Banda Black Rio'},\n",
+ " {'ArtistId': 39, 'Name': 'Fernanda Porto'},\n",
+ " {'ArtistId': 40, 'Name': 'Os Cariocas'},\n",
+ " {'ArtistId': 41, 'Name': 'Elis Regina'},\n",
+ " {'ArtistId': 42, 'Name': 'Milton Nascimento'},\n",
+ " {'ArtistId': 43, 'Name': 'A Cor Do Som'},\n",
+ " {'ArtistId': 44, 'Name': 'Kid Abelha'},\n",
+ " {'ArtistId': 45, 'Name': 'Sandra De Sá'},\n",
+ " {'ArtistId': 46, 'Name': 'Jorge Ben'},\n",
+ " {'ArtistId': 47, 'Name': 'Hermeto Pascoal'},\n",
+ " {'ArtistId': 48, 'Name': 'Barão Vermelho'},\n",
+ " {'ArtistId': 49,\n",
+ " 'Name': 'Edson, DJ Marky & DJ Patife Featuring Fernanda Porto'},\n",
+ " {'ArtistId': 50, 'Name': 'Metallica'},\n",
+ " {'ArtistId': 51, 'Name': 'Queen'},\n",
+ " {'ArtistId': 52, 'Name': 'Kiss'},\n",
+ " {'ArtistId': 53, 'Name': 'Spyro Gyra'},\n",
+ " {'ArtistId': 54, 'Name': 'Green Day'},\n",
+ " {'ArtistId': 55, 'Name': 'David Coverdale'},\n",
+ " {'ArtistId': 56, 'Name': 'Gonzaguinha'},\n",
+ " {'ArtistId': 57, 'Name': 'Os Mutantes'},\n",
+ " {'ArtistId': 58, 'Name': 'Deep Purple'},\n",
+ " {'ArtistId': 59, 'Name': 'Santana'},\n",
+ " {'ArtistId': 60, 'Name': 'Santana Feat. Dave Matthews'},\n",
+ " {'ArtistId': 61, 'Name': 'Santana Feat. Everlast'},\n",
+ " {'ArtistId': 62, 'Name': 'Santana Feat. Rob Thomas'},\n",
+ " {'ArtistId': 63, 'Name': 'Santana Feat. Lauryn Hill & Cee-Lo'},\n",
+ " {'ArtistId': 64, 'Name': 'Santana Feat. The Project G&B'},\n",
+ " {'ArtistId': 65, 'Name': 'Santana Feat. Maná'},\n",
+ " {'ArtistId': 66, 'Name': 'Santana Feat. Eagle-Eye Cherry'},\n",
+ " {'ArtistId': 67, 'Name': 'Santana Feat. Eric Clapton'},\n",
+ " {'ArtistId': 68, 'Name': 'Miles Davis'},\n",
+ " {'ArtistId': 69, 'Name': 'Gene Krupa'},\n",
+ " {'ArtistId': 70, 'Name': 'Toquinho & Vinícius'},\n",
+ " {'ArtistId': 71, 'Name': 'Vinícius De Moraes & Baden Powell'},\n",
+ " {'ArtistId': 72, 'Name': 'Vinícius De Moraes'},\n",
+ " {'ArtistId': 73, 'Name': 'Vinícius E Qurteto Em Cy'},\n",
+ " {'ArtistId': 74, 'Name': 'Vinícius E Odette Lara'},\n",
+ " {'ArtistId': 75, 'Name': 'Vinicius, Toquinho & Quarteto Em Cy'},\n",
+ " {'ArtistId': 76, 'Name': 'Creedence Clearwater Revival'},\n",
+ " {'ArtistId': 77, 'Name': 'Cássia Eller'},\n",
+ " {'ArtistId': 78, 'Name': 'Def Leppard'},\n",
+ " {'ArtistId': 79, 'Name': 'Dennis Chambers'},\n",
+ " {'ArtistId': 80, 'Name': 'Djavan'},\n",
+ " {'ArtistId': 81, 'Name': 'Eric Clapton'},\n",
+ " {'ArtistId': 82, 'Name': 'Faith No More'},\n",
+ " {'ArtistId': 83, 'Name': 'Falamansa'},\n",
+ " {'ArtistId': 84, 'Name': 'Foo Fighters'},\n",
+ " {'ArtistId': 85, 'Name': 'Frank Sinatra'},\n",
+ " {'ArtistId': 86, 'Name': 'Funk Como Le Gusta'},\n",
+ " {'ArtistId': 87, 'Name': 'Godsmack'},\n",
+ " {'ArtistId': 88, 'Name': \"Guns N' Roses\"},\n",
+ " {'ArtistId': 89, 'Name': 'Incognito'},\n",
+ " {'ArtistId': 90, 'Name': 'Iron Maiden'},\n",
+ " {'ArtistId': 91, 'Name': 'James Brown'},\n",
+ " {'ArtistId': 92, 'Name': 'Jamiroquai'},\n",
+ " {'ArtistId': 93, 'Name': 'JET'},\n",
+ " {'ArtistId': 94, 'Name': 'Jimi Hendrix'},\n",
+ " {'ArtistId': 95, 'Name': 'Joe Satriani'},\n",
+ " {'ArtistId': 96, 'Name': 'Jota Quest'},\n",
+ " {'ArtistId': 97, 'Name': 'João Suplicy'},\n",
+ " {'ArtistId': 98, 'Name': 'Judas Priest'},\n",
+ " {'ArtistId': 99, 'Name': 'Legião Urbana'},\n",
+ " {'ArtistId': 100, 'Name': 'Lenny Kravitz'},\n",
+ " {'ArtistId': 101, 'Name': 'Lulu Santos'},\n",
+ " {'ArtistId': 102, 'Name': 'Marillion'},\n",
+ " {'ArtistId': 103, 'Name': 'Marisa Monte'},\n",
+ " {'ArtistId': 104, 'Name': 'Marvin Gaye'},\n",
+ " {'ArtistId': 105, 'Name': 'Men At Work'},\n",
+ " {'ArtistId': 106, 'Name': 'Motörhead'},\n",
+ " {'ArtistId': 107, 'Name': 'Motörhead & Girlschool'},\n",
+ " {'ArtistId': 108, 'Name': 'Mônica Marianno'},\n",
+ " {'ArtistId': 109, 'Name': 'Mötley Crüe'},\n",
+ " {'ArtistId': 110, 'Name': 'Nirvana'},\n",
+ " {'ArtistId': 111, 'Name': 'O Terço'},\n",
+ " {'ArtistId': 112, 'Name': 'Olodum'},\n",
+ " {'ArtistId': 113, 'Name': 'Os Paralamas Do Sucesso'},\n",
+ " {'ArtistId': 114, 'Name': 'Ozzy Osbourne'},\n",
+ " {'ArtistId': 115, 'Name': 'Page & Plant'},\n",
+ " {'ArtistId': 116, 'Name': 'Passengers'},\n",
+ " {'ArtistId': 117, 'Name': \"Paul D'Ianno\"},\n",
+ " {'ArtistId': 118, 'Name': 'Pearl Jam'},\n",
+ " {'ArtistId': 119, 'Name': 'Peter Tosh'},\n",
+ " {'ArtistId': 120, 'Name': 'Pink Floyd'},\n",
+ " {'ArtistId': 121, 'Name': 'Planet Hemp'},\n",
+ " {'ArtistId': 122, 'Name': 'R.E.M. Feat. Kate Pearson'},\n",
+ " {'ArtistId': 123, 'Name': 'R.E.M. Feat. KRS-One'},\n",
+ " {'ArtistId': 124, 'Name': 'R.E.M.'},\n",
+ " {'ArtistId': 125, 'Name': 'Raimundos'},\n",
+ " {'ArtistId': 126, 'Name': 'Raul Seixas'},\n",
+ " {'ArtistId': 127, 'Name': 'Red Hot Chili Peppers'},\n",
+ " {'ArtistId': 128, 'Name': 'Rush'},\n",
+ " {'ArtistId': 129, 'Name': 'Simply Red'},\n",
+ " {'ArtistId': 130, 'Name': 'Skank'},\n",
+ " {'ArtistId': 131, 'Name': 'Smashing Pumpkins'},\n",
+ " {'ArtistId': 132, 'Name': 'Soundgarden'},\n",
+ " {'ArtistId': 133, 'Name': 'Stevie Ray Vaughan & Double Trouble'},\n",
+ " {'ArtistId': 134, 'Name': 'Stone Temple Pilots'},\n",
+ " {'ArtistId': 135, 'Name': 'System Of A Down'},\n",
+ " {'ArtistId': 136, 'Name': 'Terry Bozzio, Tony Levin & Steve Stevens'},\n",
+ " {'ArtistId': 137, 'Name': 'The Black Crowes'},\n",
+ " {'ArtistId': 138, 'Name': 'The Clash'},\n",
+ " {'ArtistId': 139, 'Name': 'The Cult'},\n",
+ " {'ArtistId': 140, 'Name': 'The Doors'},\n",
+ " {'ArtistId': 141, 'Name': 'The Police'},\n",
+ " {'ArtistId': 142, 'Name': 'The Rolling Stones'},\n",
+ " {'ArtistId': 143, 'Name': 'The Tea Party'},\n",
+ " {'ArtistId': 144, 'Name': 'The Who'},\n",
+ " {'ArtistId': 145, 'Name': 'Tim Maia'},\n",
+ " {'ArtistId': 146, 'Name': 'Titãs'},\n",
+ " {'ArtistId': 147, 'Name': 'Battlestar Galactica'},\n",
+ " {'ArtistId': 148, 'Name': 'Heroes'},\n",
+ " {'ArtistId': 149, 'Name': 'Lost'},\n",
+ " {'ArtistId': 150, 'Name': 'U2'},\n",
+ " {'ArtistId': 151, 'Name': 'UB40'},\n",
+ " {'ArtistId': 152, 'Name': 'Van Halen'},\n",
+ " {'ArtistId': 153, 'Name': 'Velvet Revolver'},\n",
+ " {'ArtistId': 154, 'Name': 'Whitesnake'},\n",
+ " {'ArtistId': 155, 'Name': 'Zeca Pagodinho'},\n",
+ " {'ArtistId': 156, 'Name': 'The Office'},\n",
+ " {'ArtistId': 157, 'Name': 'Dread Zeppelin'},\n",
+ " {'ArtistId': 158, 'Name': 'Battlestar Galactica (Classic)'},\n",
+ " {'ArtistId': 159, 'Name': 'Aquaman'},\n",
+ " {'ArtistId': 160, 'Name': 'Christina Aguilera featuring BigElf'},\n",
+ " {'ArtistId': 161, 'Name': \"Aerosmith & Sierra Leone's Refugee Allstars\"},\n",
+ " {'ArtistId': 162, 'Name': 'Los Lonely Boys'},\n",
+ " {'ArtistId': 163, 'Name': 'Corinne Bailey Rae'},\n",
+ " {'ArtistId': 164, 'Name': 'Dhani Harrison & Jakob Dylan'},\n",
+ " {'ArtistId': 165, 'Name': 'Jackson Browne'},\n",
+ " {'ArtistId': 166, 'Name': 'Avril Lavigne'},\n",
+ " {'ArtistId': 167, 'Name': 'Big & Rich'},\n",
+ " {'ArtistId': 168, 'Name': \"Youssou N'Dour\"},\n",
+ " {'ArtistId': 169, 'Name': 'Black Eyed Peas'},\n",
+ " {'ArtistId': 170, 'Name': 'Jack Johnson'},\n",
+ " {'ArtistId': 171, 'Name': 'Ben Harper'},\n",
+ " {'ArtistId': 172, 'Name': 'Snow Patrol'},\n",
+ " {'ArtistId': 173, 'Name': 'Matisyahu'},\n",
+ " {'ArtistId': 174, 'Name': 'The Postal Service'},\n",
+ " {'ArtistId': 175, 'Name': 'Jaguares'},\n",
+ " {'ArtistId': 176, 'Name': 'The Flaming Lips'},\n",
+ " {'ArtistId': 177, 'Name': \"Jack's Mannequin & Mick Fleetwood\"},\n",
+ " {'ArtistId': 178, 'Name': 'Regina Spektor'},\n",
+ " {'ArtistId': 179, 'Name': 'Scorpions'},\n",
+ " {'ArtistId': 180, 'Name': 'House Of Pain'},\n",
+ " {'ArtistId': 181, 'Name': 'Xis'},\n",
+ " {'ArtistId': 182, 'Name': 'Nega Gizza'},\n",
+ " {'ArtistId': 183, 'Name': 'Gustavo & Andres Veiga & Salazar'},\n",
+ " {'ArtistId': 184, 'Name': 'Rodox'},\n",
+ " {'ArtistId': 185, 'Name': 'Charlie Brown Jr.'},\n",
+ " {'ArtistId': 186, 'Name': 'Pedro Luís E A Parede'},\n",
+ " {'ArtistId': 187, 'Name': 'Los Hermanos'},\n",
+ " {'ArtistId': 188, 'Name': 'Mundo Livre S/A'},\n",
+ " {'ArtistId': 189, 'Name': 'Otto'},\n",
+ " {'ArtistId': 190, 'Name': 'Instituto'},\n",
+ " {'ArtistId': 191, 'Name': 'Nação Zumbi'},\n",
+ " {'ArtistId': 192, 'Name': 'DJ Dolores & Orchestra Santa Massa'},\n",
+ " {'ArtistId': 193, 'Name': 'Seu Jorge'},\n",
+ " {'ArtistId': 194, 'Name': 'Sabotage E Instituto'},\n",
+ " {'ArtistId': 195, 'Name': 'Stereo Maracana'},\n",
+ " {'ArtistId': 196, 'Name': 'Cake'},\n",
+ " {'ArtistId': 197, 'Name': 'Aisha Duo'},\n",
+ " {'ArtistId': 198, 'Name': 'Habib Koité and Bamada'},\n",
+ " {'ArtistId': 199, 'Name': 'Karsh Kale'},\n",
+ " {'ArtistId': 200, 'Name': 'The Posies'},\n",
+ " {'ArtistId': 201, 'Name': 'Luciana Souza/Romero Lubambo'},\n",
+ " {'ArtistId': 202, 'Name': 'Aaron Goldberg'},\n",
+ " {'ArtistId': 203, 'Name': 'Nicolaus Esterhazy Sinfonia'},\n",
+ " {'ArtistId': 204, 'Name': 'Temple of the Dog'},\n",
+ " {'ArtistId': 205, 'Name': 'Chris Cornell'},\n",
+ " {'ArtistId': 206, 'Name': 'Alberto Turco & Nova Schola Gregoriana'},\n",
+ " {'ArtistId': 207,\n",
+ " 'Name': 'Richard Marlow & The Choir of Trinity College, Cambridge'},\n",
+ " {'ArtistId': 208, 'Name': 'English Concert & Trevor Pinnock'},\n",
+ " {'ArtistId': 209,\n",
+ " 'Name': 'Anne-Sophie Mutter, Herbert Von Karajan & Wiener Philharmoniker'},\n",
+ " {'ArtistId': 210,\n",
+ " 'Name': 'Hilary Hahn, Jeffrey Kahane, Los Angeles Chamber Orchestra & Margaret Batjer'},\n",
+ " {'ArtistId': 211, 'Name': 'Wilhelm Kempff'},\n",
+ " {'ArtistId': 212, 'Name': 'Yo-Yo Ma'},\n",
+ " {'ArtistId': 213, 'Name': 'Scholars Baroque Ensemble'},\n",
+ " {'ArtistId': 214,\n",
+ " 'Name': 'Academy of St. Martin in the Fields & Sir Neville Marriner'},\n",
+ " {'ArtistId': 215,\n",
+ " 'Name': 'Academy of St. Martin in the Fields Chamber Ensemble & Sir Neville Marriner'},\n",
+ " {'ArtistId': 216,\n",
+ " 'Name': 'Berliner Philharmoniker, Claudio Abbado & Sabine Meyer'},\n",
+ " {'ArtistId': 217,\n",
+ " 'Name': 'Royal Philharmonic Orchestra & Sir Thomas Beecham'},\n",
+ " {'ArtistId': 218,\n",
+ " 'Name': 'Orchestre Révolutionnaire et Romantique & John Eliot Gardiner'},\n",
+ " {'ArtistId': 219, 'Name': 'Britten Sinfonia, Ivor Bolton & Lesley Garrett'},\n",
+ " {'ArtistId': 220,\n",
+ " 'Name': 'Chicago Symphony Chorus, Chicago Symphony Orchestra & Sir Georg Solti'},\n",
+ " {'ArtistId': 221, 'Name': 'Sir Georg Solti & Wiener Philharmoniker'},\n",
+ " {'ArtistId': 222,\n",
+ " 'Name': 'Academy of St. Martin in the Fields, John Birch, Sir Neville Marriner & Sylvia McNair'},\n",
+ " {'ArtistId': 223,\n",
+ " 'Name': 'London Symphony Orchestra & Sir Charles Mackerras'},\n",
+ " {'ArtistId': 224, 'Name': 'Barry Wordsworth & BBC Concert Orchestra'},\n",
+ " {'ArtistId': 225,\n",
+ " 'Name': 'Herbert Von Karajan, Mirella Freni & Wiener Philharmoniker'},\n",
+ " {'ArtistId': 226, 'Name': 'Eugene Ormandy'},\n",
+ " {'ArtistId': 227, 'Name': 'Luciano Pavarotti'},\n",
+ " {'ArtistId': 228, 'Name': 'Leonard Bernstein & New York Philharmonic'},\n",
+ " {'ArtistId': 229, 'Name': 'Boston Symphony Orchestra & Seiji Ozawa'},\n",
+ " {'ArtistId': 230, 'Name': 'Aaron Copland & London Symphony Orchestra'},\n",
+ " {'ArtistId': 231, 'Name': 'Ton Koopman'},\n",
+ " {'ArtistId': 232, 'Name': 'Sergei Prokofiev & Yuri Temirkanov'},\n",
+ " {'ArtistId': 233, 'Name': 'Chicago Symphony Orchestra & Fritz Reiner'},\n",
+ " {'ArtistId': 234, 'Name': 'Orchestra of The Age of Enlightenment'},\n",
+ " {'ArtistId': 235,\n",
+ " 'Name': 'Emanuel Ax, Eugene Ormandy & Philadelphia Orchestra'},\n",
+ " {'ArtistId': 236, 'Name': 'James Levine'},\n",
+ " {'ArtistId': 237, 'Name': 'Berliner Philharmoniker & Hans Rosbaud'},\n",
+ " {'ArtistId': 238, 'Name': 'Maurizio Pollini'},\n",
+ " {'ArtistId': 239,\n",
+ " 'Name': 'Academy of St. Martin in the Fields, Sir Neville Marriner & William Bennett'},\n",
+ " {'ArtistId': 240, 'Name': 'Gustav Mahler'},\n",
+ " {'ArtistId': 241,\n",
+ " 'Name': 'Felix Schmidt, London Symphony Orchestra & Rafael Frühbeck de Burgos'},\n",
+ " {'ArtistId': 242, 'Name': 'Edo de Waart & San Francisco Symphony'},\n",
+ " {'ArtistId': 243, 'Name': 'Antal Doráti & London Symphony Orchestra'},\n",
+ " {'ArtistId': 244, 'Name': 'Choir Of Westminster Abbey & Simon Preston'},\n",
+ " {'ArtistId': 245, 'Name': 'Michael Tilson Thomas & San Francisco Symphony'},\n",
+ " {'ArtistId': 246,\n",
+ " 'Name': 'Chor der Wiener Staatsoper, Herbert Von Karajan & Wiener Philharmoniker'},\n",
+ " {'ArtistId': 247, 'Name': \"The King's Singers\"},\n",
+ " {'ArtistId': 248, 'Name': 'Berliner Philharmoniker & Herbert Von Karajan'},\n",
+ " {'ArtistId': 249, 'Name': 'Sir Georg Solti, Sumi Jo & Wiener Philharmoniker'},\n",
+ " {'ArtistId': 250, 'Name': \"Christopher O'Riley\"},\n",
+ " {'ArtistId': 251, 'Name': 'Fretwork'},\n",
+ " {'ArtistId': 252, 'Name': 'Amy Winehouse'},\n",
+ " {'ArtistId': 253, 'Name': 'Calexico'},\n",
+ " {'ArtistId': 254, 'Name': 'Otto Klemperer & Philharmonia Orchestra'},\n",
+ " {'ArtistId': 255, 'Name': 'Yehudi Menuhin'},\n",
+ " {'ArtistId': 256, 'Name': 'Philharmonia Orchestra & Sir Neville Marriner'},\n",
+ " {'ArtistId': 257,\n",
+ " 'Name': 'Academy of St. Martin in the Fields, Sir Neville Marriner & Thurston Dart'},\n",
+ " {'ArtistId': 258, 'Name': 'Les Arts Florissants & William Christie'},\n",
+ " {'ArtistId': 259, 'Name': 'The 12 Cellists of The Berlin Philharmonic'},\n",
+ " {'ArtistId': 260, 'Name': 'Adrian Leaper & Doreen de Feis'},\n",
+ " {'ArtistId': 261, 'Name': 'Roger Norrington, London Classical Players'},\n",
+ " {'ArtistId': 262,\n",
+ " 'Name': \"Charles Dutoit & L'Orchestre Symphonique de Montréal\"},\n",
+ " {'ArtistId': 263,\n",
+ " 'Name': 'Equale Brass Ensemble, John Eliot Gardiner & Munich Monteverdi Orchestra and Choir'},\n",
+ " {'ArtistId': 264, 'Name': \"Kent Nagano and Orchestre de l'Opéra de Lyon\"},\n",
+ " {'ArtistId': 265, 'Name': 'Julian Bream'},\n",
+ " {'ArtistId': 266, 'Name': 'Martin Roscoe'},\n",
+ " {'ArtistId': 267, 'Name': 'Göteborgs Symfoniker & Neeme Järvi'},\n",
+ " {'ArtistId': 268, 'Name': 'Itzhak Perlman'},\n",
+ " {'ArtistId': 269, 'Name': 'Michele Campanella'},\n",
+ " {'ArtistId': 270, 'Name': 'Gerald Moore'},\n",
+ " {'ArtistId': 271, 'Name': 'Mela Tenenbaum, Pro Musica Prague & Richard Kapp'},\n",
+ " {'ArtistId': 272, 'Name': 'Emerson String Quartet'},\n",
+ " {'ArtistId': 273,\n",
+ " 'Name': 'C. Monteverdi, Nigel Rogers - Chiaroscuro; London Baroque; London Cornett & Sackbu'},\n",
+ " {'ArtistId': 274, 'Name': 'Nash Ensemble'},\n",
+ " {'ArtistId': 275, 'Name': 'Philip Glass Ensemble'}]"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "artist()"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -138,7 +453,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 6,
"metadata": {},
"outputs": [
{
@@ -151,7 +466,7 @@
" ]"
]
},
- "execution_count": null,
+ "execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
@@ -183,7 +498,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 7,
"metadata": {},
"outputs": [
{
@@ -192,7 +507,7 @@
"True"
]
},
- "execution_count": null,
+ "execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@@ -210,7 +525,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 8,
"metadata": {},
"outputs": [
{
@@ -219,7 +534,7 @@
"ArtistId, Name"
]
},
- "execution_count": null,
+ "execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -252,7 +567,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 9,
"metadata": {},
"outputs": [
{
@@ -277,7 +592,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 10,
"metadata": {},
"outputs": [
{
@@ -286,7 +601,7 @@
"[{'ArtistId': 1, 'Name': 'AC/DC'}]"
]
},
- "execution_count": null,
+ "execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
@@ -304,7 +619,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 11,
"metadata": {},
"outputs": [
{
@@ -316,7 +631,7 @@
" {'AlbumId': 4, 'Title': 'Let There Be Rock', 'ArtistId': 1}]"
]
},
- "execution_count": null,
+ "execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
@@ -349,7 +664,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
@@ -365,7 +680,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 13,
"metadata": {},
"outputs": [
{
@@ -374,7 +689,7 @@
"Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1)"
]
},
- "execution_count": null,
+ "execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
@@ -393,7 +708,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 14,
"metadata": {},
"outputs": [
{
@@ -412,7 +727,7 @@
""
]
},
- "execution_count": null,
+ "execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@@ -431,7 +746,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
@@ -440,7 +755,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 16,
"metadata": {},
"outputs": [
{
@@ -449,7 +764,7 @@
"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)"
]
},
- "execution_count": null,
+ "execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
@@ -469,7 +784,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 17,
"metadata": {},
"outputs": [
{
@@ -479,7 +794,7 @@
" Album(AlbumId=2, Title='Balls to the Wall', ArtistId=2)]"
]
},
- "execution_count": null,
+ "execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
@@ -497,7 +812,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 18,
"metadata": {},
"outputs": [
{
@@ -508,7 +823,7 @@
" (2, Album(AlbumId=2, Title='Balls to the Wall', ArtistId=2))]"
]
},
- "execution_count": null,
+ "execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
@@ -526,50 +841,49 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "Album(AlbumId=1, Title='For Those About To Rock We Salute You', ArtistId=1)"
+ "Album(AlbumId=5, Title='Big Ones', ArtistId=3)"
]
},
- "execution_count": null,
+ "execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
- "album.get(1)"
+ "album.get(5)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "If you want the dataclass-conversion behaviour for *all* tables (and optionally views) then you can create them all at once with `all_dcs`."
+ "If you set `xtra` fields, then `get` 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:"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 20,
"metadata": {},
"outputs": [
{
- "data": {
- "text/plain": [
- "types.Album"
- ]
- },
- "execution_count": null,
- "metadata": {},
- "output_type": "execute_result"
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Not found\n"
+ ]
}
],
"source": [
- "dcs = all_dcs(db)\n",
- "dcs[0]"
+ "album.xtra(ArtistId=1)\n",
+ "\n",
+ "try: album.get(5)\n",
+ "except NotFoundError: print(\"Not found\")"
]
},
{
@@ -603,7 +917,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 21,
"metadata": {},
"outputs": [
{
@@ -612,7 +926,7 @@
""
]
},
- "execution_count": null,
+ "execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
@@ -631,7 +945,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 22,
"metadata": {},
"outputs": [
{
@@ -641,7 +955,8 @@
"CREATE TABLE [cats] (\n",
" [id] INTEGER PRIMARY KEY,\n",
" [name] TEXT,\n",
- " [weight] FLOAT\n",
+ " [weight] FLOAT,\n",
+ " [uid] INTEGER\n",
")\n",
"```"
],
@@ -649,13 +964,13 @@
""
]
},
- "execution_count": null,
+ "execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
- "cats.create(id=int, name=str, weight=float, pk='id')\n",
+ "cats.create(id=int, name=str, weight=float, uid=int, pk='id')\n",
"hl_md(cats.schema, 'sql')"
]
},
@@ -663,15 +978,16 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "...the same applies to `insert` here:"
+ "It we set `xtra` then the additional fields are used for `insert`, `update`, and `delete`:"
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
+ "cats.xtra(uid=2)\n",
"cat = cats.insert(name='meow', weight=6)"
]
},
@@ -679,21 +995,21 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "The inserted row is returned."
+ "The inserted row is returned, including the xtra 'uid' field."
]
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "{'id': 1, 'name': 'meow', 'weight': 6.0}"
+ "{'id': 1, 'name': 'meow', 'weight': 6.0, 'uid': 2}"
]
},
- "execution_count": null,
+ "execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
@@ -711,26 +1027,55 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "[{'id': 1, 'name': 'moo', 'weight': 6.0}]"
+ "[{'id': 1, 'name': 'moo', 'weight': 6.0, 'uid': 2}]"
]
},
- "execution_count": null,
+ "execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cat['name'] = \"moo\"\n",
+ "cat['uid'] = 1\n",
"cats.update(**cat)\n",
"cats()"
]
},
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Attempts to update or insert with xtra fields are ignored.\n",
+ "\n",
+ "An error is raised if there's an attempt to update a record not matching `xtra` fields:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Not found\n"
+ ]
+ }
+ ],
+ "source": [
+ "cats.xtra(uid=1)\n",
+ "try: cats.update(**cat)\n",
+ "except NotFoundError: print(\"Not found\")"
+ ]
+ },
{
"cell_type": "markdown",
"metadata": {},
@@ -740,21 +1085,22 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "Cats(id=1, name='moo', weight=6.0)"
+ "Cats(id=1, name='moo', weight=6.0, uid=2)"
]
},
- "execution_count": null,
+ "execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
+ "cats.xtra(uid=2)\n",
"cats.dataclass()\n",
"cat = cats.get(1)\n",
"cat"
@@ -762,16 +1108,16 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "[Cats(id=1, name='foo', weight=6.0)]"
+ "[Cats(id=1, name='foo', weight=6.0, uid=2)]"
]
},
- "execution_count": null,
+ "execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
@@ -784,7 +1130,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 29,
"metadata": {},
"outputs": [
{
@@ -793,7 +1139,7 @@
""
]
},
- "execution_count": null,
+ "execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
@@ -819,7 +1165,7 @@
},
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 30,
"metadata": {},
"outputs": [
{
@@ -1134,10 +1480,10 @@
"\n"
],
"text/plain": [
- ""
+ ""
]
},
- "execution_count": null,
+ "execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
@@ -1310,9 +1656,21 @@
],
"metadata": {
"kernelspec": {
- "display_name": "python3",
+ "display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.8"
}
},
"nbformat": 4,