Skip to content

Commit 57d79b7

Browse files
NickCrewscpcloud
andauthored
feat(backends): fixup drop_database() when passing a specific catalog (#11110)
Co-authored-by: Phillip Cloud <[email protected]>
1 parent d55a5ee commit 57d79b7

File tree

7 files changed

+62
-34
lines changed

7 files changed

+62
-34
lines changed

ibis/backends/clickhouse/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -570,8 +570,12 @@ def create_database(
570570
with self._safe_raw_sql(src):
571571
pass
572572

573-
def drop_database(self, name: str, /, *, force: bool = False) -> None:
574-
src = sge.Drop(this=sg.to_identifier(name), kind="DATABASE", exists=force)
573+
def drop_database(
574+
self, name: str, /, *, catalog: str | None = None, force: bool = False
575+
) -> None:
576+
src = sge.Drop(
577+
this=sg.table(name, catalog=catalog), kind="DATABASE", exists=force
578+
)
575579
with self._safe_raw_sql(src):
576580
pass
577581

ibis/backends/duckdb/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ def create_database(
508508
def drop_database(
509509
self, name: str, /, *, catalog: str | None = None, force: bool = False
510510
) -> None:
511-
if catalog is not None:
511+
if catalog is not None and catalog != self.current_catalog:
512512
raise exc.UnsupportedOperationError(
513513
"DuckDB cannot drop a database in another catalog."
514514
)
Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
from __future__ import annotations
22

3+
import duckdb
34
import pandas as pd
45
import pandas.testing as tm
56
import pytest
67

78
import ibis
89
import ibis.common.exceptions as exc
10+
from ibis.util import gen_name
911

1012

11-
@pytest.fixture(scope="session")
12-
def external_duckdb_file(tmpdir_factory): # pragma: no cover
13-
ddb_path = str(tmpdir_factory.mktemp("data") / "starwars.ddb")
13+
@pytest.fixture
14+
def external_duckdb_file(tmpdir): # pragma: no cover
15+
ddb_path = str(tmpdir / "starwars.ddb")
1416
con = ibis.duckdb.connect(ddb_path)
1517

16-
starwars_df = pd.DataFrame(
17-
{
18-
"name": ["Luke Skywalker", "C-3PO", "R2-D2"],
19-
"height": [172, 167, 96],
20-
"mass": [77.0, 75.0, 32.0],
21-
}
22-
)
23-
con.create_table("starwars", obj=starwars_df)
24-
con.disconnect()
18+
try:
19+
starwars_df = pd.DataFrame(
20+
{
21+
"name": ["Luke Skywalker", "C-3PO", "R2-D2"],
22+
"height": [172, 167, 96],
23+
"mass": [77.0, 75.0, 32.0],
24+
}
25+
)
26+
con.create_table("starwars", obj=starwars_df)
27+
finally:
28+
con.disconnect()
2529

2630
return ddb_path, starwars_df
2731

@@ -30,44 +34,57 @@ def test_read_write_external_catalog(con, external_duckdb_file, monkeypatch):
3034
monkeypatch.setattr(ibis.options, "default_backend", con)
3135

3236
ddb_path, starwars_df = external_duckdb_file
33-
con.attach(ddb_path, name="ext")
37+
name = gen_name("ext")
38+
con.attach(ddb_path, name=name)
3439

3540
# Read from catalog
36-
assert "ext" in con.list_catalogs()
37-
assert "main" in con.list_databases(catalog="ext")
41+
assert name in con.list_catalogs()
42+
assert "main" in con.list_databases(catalog=name)
3843

39-
assert "starwars" in con.list_tables(database="ext.main")
44+
db = f"{name}.main"
45+
46+
assert "starwars" in con.list_tables(database=db)
4047
assert "starwars" not in con.list_tables()
4148

42-
starwars = con.table("starwars", database="ext.main")
49+
starwars = con.table("starwars", database=db)
4350
tm.assert_frame_equal(starwars.to_pandas(), starwars_df)
4451

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

48-
_ = con.create_table("t2", obj=t, database="ext.main")
55+
_ = con.create_table("t2", obj=t, database=db)
4956

50-
assert "t2" in con.list_tables(database="ext.main")
57+
assert "t2" in con.list_tables(database=db)
5158
assert "t2" not in con.list_tables()
5259

53-
table = con.table("t2", database="ext.main")
60+
table = con.table("t2", database=db)
5461

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

5764
# Overwrite table in catalog
5865

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

61-
_ = con.create_table("t2", obj=t_overwrite, database="ext.main", overwrite=True)
68+
_ = con.create_table("t2", obj=t_overwrite, database=db, overwrite=True)
6269

63-
assert "t2" in con.list_tables(database="ext.main")
70+
assert "t2" in con.list_tables(database=db)
6471
assert "t2" not in con.list_tables()
6572

66-
table = con.table("t2", database="ext.main")
73+
table = con.table("t2", database=db)
6774

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

7077

7178
def test_raise_if_catalog_and_temp(con):
7279
with pytest.raises(exc.UnsupportedArgumentError):
7380
con.create_table("some_table", obj="hi", temp=True, database="ext.main")
81+
82+
83+
def test_cant_drop_database_external_catalog(con, tmpdir):
84+
name = gen_name("foobar")
85+
path = str(tmpdir / "f{name}.ddb")
86+
with duckdb.connect(path):
87+
pass
88+
con.attach(path)
89+
with pytest.raises(exc.UnsupportedOperationError):
90+
con.drop_database("main", catalog=name)

ibis/backends/mysql/__init__.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,12 @@ def create_database(self, name: str, force: bool = False) -> None:
255255
with self.begin() as cur:
256256
cur.execute(sql)
257257

258-
def drop_database(self, name: str, force: bool = False) -> None:
259-
sql = sge.Drop(kind="DATABASE", exists=force, this=sg.to_identifier(name)).sql(
260-
self.name
261-
)
258+
def drop_database(
259+
self, name: str, *, catalog: str | None = None, force: bool = False
260+
) -> None:
261+
sql = sge.Drop(
262+
kind="DATABASE", exists=force, this=sg.table(name, catalog=catalog)
263+
).sql(self.name)
262264
with self.begin() as cur:
263265
cur.execute(sql)
264266

ibis/backends/postgres/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ def drop_database(
600600

601601
sql = sge.Drop(
602602
kind="SCHEMA",
603-
this=sg.table(name, catalog=catalog),
603+
this=sg.table(name),
604604
exists=force,
605605
cascade=cascade,
606606
).sql(self.dialect)

ibis/backends/risingwave/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ def drop_database(
401401

402402
sql = sge.Drop(
403403
kind="SCHEMA",
404-
this=sg.table(name, catalog=catalog),
404+
this=sg.table(name),
405405
exists=force,
406406
cascade=cascade,
407407
)

ibis/backends/tests/test_client.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,11 +1441,16 @@ def test_create_catalog(con_create_catalog):
14411441
assert catalog not in con_create_catalog.list_catalogs()
14421442

14431443

1444-
def test_create_database(con_create_database):
1444+
@pytest.mark.parametrize("catalog", [None, "current_catalog"])
1445+
def test_create_database(con_create_database, catalog):
14451446
database = gen_name("test_create_database")
14461447
con_create_database.create_database(database)
14471448
assert database in con_create_database.list_databases()
1448-
con_create_database.drop_database(database)
1449+
if catalog is None:
1450+
catalog = None
1451+
else:
1452+
catalog = getattr(con_create_database, "current_catalog", None)
1453+
con_create_database.drop_database(database, catalog=catalog)
14491454
assert database not in con_create_database.list_databases()
14501455

14511456

0 commit comments

Comments
 (0)