Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions ibis/backends/clickhouse/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -570,8 +570,12 @@ def create_database(
with self._safe_raw_sql(src):
pass

def drop_database(self, name: str, /, *, force: bool = False) -> None:
src = sge.Drop(this=sg.to_identifier(name), kind="DATABASE", exists=force)
def drop_database(
self, name: str, /, *, catalog: str | None = None, force: bool = False
) -> None:
src = sge.Drop(
this=sg.table(name, catalog=catalog), kind="DATABASE", exists=force
)
with self._safe_raw_sql(src):
pass

Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/duckdb/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ def create_database(
def drop_database(
self, name: str, /, *, catalog: str | None = None, force: bool = False
) -> None:
if catalog is not None:
if catalog is not None and catalog != self.current_catalog:
raise exc.UnsupportedOperationError(
"DuckDB cannot drop a database in another catalog."
)
Expand Down
63 changes: 40 additions & 23 deletions ibis/backends/duckdb/tests/test_catalog.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,31 @@
from __future__ import annotations

import duckdb

Check warning on line 3 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L3

Added line #L3 was not covered by tests
import pandas as pd
import pandas.testing as tm
import pytest

import ibis
import ibis.common.exceptions as exc
from ibis.util import gen_name

Check warning on line 10 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L10

Added line #L10 was not covered by tests


@pytest.fixture(scope="session")
def external_duckdb_file(tmpdir_factory): # pragma: no cover
ddb_path = str(tmpdir_factory.mktemp("data") / "starwars.ddb")
@pytest.fixture
def external_duckdb_file(tmpdir): # pragma: no cover
ddb_path = str(tmpdir / "starwars.ddb")
con = ibis.duckdb.connect(ddb_path)

starwars_df = pd.DataFrame(
{
"name": ["Luke Skywalker", "C-3PO", "R2-D2"],
"height": [172, 167, 96],
"mass": [77.0, 75.0, 32.0],
}
)
con.create_table("starwars", obj=starwars_df)
con.disconnect()
try:
starwars_df = pd.DataFrame(
{
"name": ["Luke Skywalker", "C-3PO", "R2-D2"],
"height": [172, 167, 96],
"mass": [77.0, 75.0, 32.0],
}
)
con.create_table("starwars", obj=starwars_df)
finally:
con.disconnect()

return ddb_path, starwars_df

Expand All @@ -30,44 +34,57 @@
monkeypatch.setattr(ibis.options, "default_backend", con)

ddb_path, starwars_df = external_duckdb_file
con.attach(ddb_path, name="ext")
name = gen_name("ext")
con.attach(ddb_path, name=name)

Check warning on line 38 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L37-L38

Added lines #L37 - L38 were not covered by tests

# Read from catalog
assert "ext" in con.list_catalogs()
assert "main" in con.list_databases(catalog="ext")
assert name in con.list_catalogs()
assert "main" in con.list_databases(catalog=name)

Check warning on line 42 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L41-L42

Added lines #L41 - L42 were not covered by tests

assert "starwars" in con.list_tables(database="ext.main")
db = f"{name}.main"

Check warning on line 44 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L44

Added line #L44 was not covered by tests

assert "starwars" in con.list_tables(database=db)

Check warning on line 46 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L46

Added line #L46 was not covered by tests
assert "starwars" not in con.list_tables()

starwars = con.table("starwars", database="ext.main")
starwars = con.table("starwars", database=db)

Check warning on line 49 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L49

Added line #L49 was not covered by tests
tm.assert_frame_equal(starwars.to_pandas(), starwars_df)

# Write to catalog
t = ibis.memtable([{"a": 1, "b": "foo"}, {"a": 2, "b": "baz"}])

_ = con.create_table("t2", obj=t, database="ext.main")
_ = con.create_table("t2", obj=t, database=db)

Check warning on line 55 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L55

Added line #L55 was not covered by tests

assert "t2" in con.list_tables(database="ext.main")
assert "t2" in con.list_tables(database=db)

Check warning on line 57 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L57

Added line #L57 was not covered by tests
assert "t2" not in con.list_tables()

table = con.table("t2", database="ext.main")
table = con.table("t2", database=db)

Check warning on line 60 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L60

Added line #L60 was not covered by tests

tm.assert_frame_equal(t.to_pandas(), table.to_pandas())

# Overwrite table in catalog

t_overwrite = ibis.memtable([{"a": 8, "b": "bing"}, {"a": 9, "b": "bong"}])

_ = con.create_table("t2", obj=t_overwrite, database="ext.main", overwrite=True)
_ = con.create_table("t2", obj=t_overwrite, database=db, overwrite=True)

Check warning on line 68 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L68

Added line #L68 was not covered by tests

assert "t2" in con.list_tables(database="ext.main")
assert "t2" in con.list_tables(database=db)

Check warning on line 70 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L70

Added line #L70 was not covered by tests
assert "t2" not in con.list_tables()

table = con.table("t2", database="ext.main")
table = con.table("t2", database=db)

Check warning on line 73 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L73

Added line #L73 was not covered by tests

tm.assert_frame_equal(t_overwrite.to_pandas(), table.to_pandas())


def test_raise_if_catalog_and_temp(con):
with pytest.raises(exc.UnsupportedArgumentError):
con.create_table("some_table", obj="hi", temp=True, database="ext.main")


def test_cant_drop_database_external_catalog(con, tmpdir):
name = gen_name("foobar")
path = str(tmpdir / "f{name}.ddb")
with duckdb.connect(path):
pass
con.attach(path)
with pytest.raises(exc.UnsupportedOperationError):
con.drop_database("main", catalog=name)

Check warning on line 90 in ibis/backends/duckdb/tests/test_catalog.py

View check run for this annotation

Codecov / codecov/patch

ibis/backends/duckdb/tests/test_catalog.py#L83-L90

Added lines #L83 - L90 were not covered by tests
10 changes: 6 additions & 4 deletions ibis/backends/mysql/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,12 @@ def create_database(self, name: str, force: bool = False) -> None:
with self.begin() as cur:
cur.execute(sql)

def drop_database(self, name: str, force: bool = False) -> None:
sql = sge.Drop(kind="DATABASE", exists=force, this=sg.to_identifier(name)).sql(
self.name
)
def drop_database(
self, name: str, *, catalog: str | None = None, force: bool = False
) -> None:
sql = sge.Drop(
kind="DATABASE", exists=force, this=sg.table(name, catalog=catalog)
).sql(self.name)
with self.begin() as cur:
cur.execute(sql)

Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/postgres/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ def drop_database(

sql = sge.Drop(
kind="SCHEMA",
this=sg.table(name, catalog=catalog),
this=sg.table(name),
exists=force,
cascade=cascade,
).sql(self.dialect)
Expand Down
2 changes: 1 addition & 1 deletion ibis/backends/risingwave/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ def drop_database(

sql = sge.Drop(
kind="SCHEMA",
this=sg.table(name, catalog=catalog),
this=sg.table(name),
exists=force,
cascade=cascade,
)
Expand Down
9 changes: 7 additions & 2 deletions ibis/backends/tests/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1441,11 +1441,16 @@ def test_create_catalog(con_create_catalog):
assert catalog not in con_create_catalog.list_catalogs()


def test_create_database(con_create_database):
@pytest.mark.parametrize("catalog", [None, "current_catalog"])
def test_create_database(con_create_database, catalog):
database = gen_name("test_create_database")
con_create_database.create_database(database)
assert database in con_create_database.list_databases()
con_create_database.drop_database(database)
if catalog is None:
catalog = None
else:
catalog = getattr(con_create_database, "current_catalog", None)
con_create_database.drop_database(database, catalog=catalog)
assert database not in con_create_database.list_databases()


Expand Down