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,