From b44ef2bd0ae05ed945b7385062dfc492ad34d2f0 Mon Sep 17 00:00:00 2001 From: Rami Abdelrazzaq Date: Sat, 7 Mar 2026 23:05:36 -0600 Subject: [PATCH] Fix #699: make db[] return tables not views --- sqlite_utils/cli.py | 8 ++++++-- sqlite_utils/db.py | 4 +--- tests/test_create.py | 11 +++++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/sqlite_utils/cli.py b/sqlite_utils/cli.py index 9b9ee20e..a32ee410 100644 --- a/sqlite_utils/cli.py +++ b/sqlite_utils/cli.py @@ -1796,7 +1796,10 @@ def drop_view(path, view, ignore, load_extension): _register_db_for_cleanup(db) _load_extensions(db, load_extension) try: - db[view].drop(ignore=ignore) + db.view(view).drop(ignore=ignore) + except sqlite_utils.db.NoView: + if not ignore: + raise click.ClickException('View "{}" does not exist'.format(view)) except OperationalError: raise click.ClickException('View "{}" does not exist'.format(view)) @@ -2039,8 +2042,9 @@ def memory( view_names = ["t{}".format(i + 1)] if i == 0: view_names.append("t") + existing_views = set(db.view_names()) for view_name in view_names: - if not db[view_name].exists(): + if view_name not in existing_views: db.create_view( view_name, "select * from {}".format(quote_identifier(file_table)), diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index aacdc893..ac3994d4 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -445,15 +445,13 @@ def tracer( finally: self._tracer = prev_tracer - def __getitem__(self, table_name: str) -> Union["Table", "View"]: + def __getitem__(self, table_name: str) -> "Table": """ ``db[table_name]`` returns a :class:`.Table` object for the table with the specified name. If the table does not exist yet it will be created the first time data is inserted into it. :param table_name: The name of the table """ - if table_name in self.view_names(): - return self.view(table_name) return self.table(table_name) def __repr__(self) -> str: diff --git a/tests/test_create.py b/tests/test_create.py index ea09c459..7ad5892e 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -1082,7 +1082,7 @@ def test_drop(fresh_db): def test_drop_view(fresh_db): fresh_db.create_view("foo_view", "select 1") assert ["foo_view"] == fresh_db.view_names() - assert None is fresh_db["foo_view"].drop() + assert None is fresh_db.view("foo_view").drop() assert [] == fresh_db.view_names() @@ -1093,7 +1093,7 @@ def test_drop_ignore(fresh_db): # Testing view is harder, we need to create it in order # to get a View object, then drop it twice fresh_db.create_view("foo_view", "select 1") - view = fresh_db["foo_view"] + view = fresh_db.view("foo_view") assert isinstance(view, View) view.drop() with pytest.raises(sqlite3.OperationalError): @@ -1381,9 +1381,12 @@ def test_bad_table_and_view_exceptions(fresh_db): with pytest.raises(NoTable) as ex: fresh_db.table("v") assert ex.value.args[0] == "Table v is actually a view" - with pytest.raises(NoView) as ex2: + with pytest.raises(NoTable) as ex2: + fresh_db["v"] + assert ex2.value.args[0] == "Table v is actually a view" + with pytest.raises(NoView) as ex3: fresh_db.view("t") - assert ex2.value.args[0] == "View t does not exist" + assert ex3.value.args[0] == "View t does not exist" # Tests for issue #655: Table configuration should be stored in _defaults