Skip to content

Commit e48317a

Browse files
committed
[python] Introduce database related commands to Python CLI
1 parent 0c22e07 commit e48317a

File tree

6 files changed

+764
-2
lines changed

6 files changed

+764
-2
lines changed

docs/content/pypaimon/cli.md

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ paimon [OPTIONS] COMMAND [ARGS]...
7676
- `-c, --config PATH`: Path to catalog configuration file (default: `paimon.yaml`)
7777
- `--help`: Show help message and exit
7878

79-
## Commands
79+
## Table Commands
8080

8181
### Table Read
8282

@@ -203,4 +203,82 @@ The schema JSON file follows the same format as output by `table get`:
203203
2. Create a new table with the same schema:
204204
```shell
205205
paimon table create mydb.users_copy --schema users_schema.json
206-
```
206+
```
207+
208+
## Database Commands
209+
210+
### DB Get
211+
212+
Get and display database information in JSON format.
213+
214+
```shell
215+
paimon db get mydb
216+
```
217+
218+
Output:
219+
```json
220+
{
221+
"name": "mydb",
222+
"options": {}
223+
}
224+
```
225+
226+
### DB Create
227+
228+
Create a new database.
229+
230+
```shell
231+
# Create a simple database
232+
paimon db create mydb
233+
234+
# Create with properties
235+
paimon db create mydb -p '{"key1": "value1", "key2": "value2"}'
236+
237+
# Create and ignore if already exists
238+
paimon db create mydb -i
239+
```
240+
241+
### DB Drop
242+
243+
Drop an existing database.
244+
245+
```shell
246+
# Drop a database
247+
paimon db drop mydb
248+
249+
# Drop and ignore if not exists
250+
paimon db drop mydb --ignore-if-not-exists
251+
252+
# Drop with all tables (cascade)
253+
paimon db drop mydb --cascade
254+
```
255+
256+
### DB Alter
257+
258+
Alter database properties by setting or removing properties.
259+
260+
```shell
261+
# Set properties
262+
paimon db alter mydb --set '{"key1": "value1", "key2": "value2"}'
263+
264+
# Remove properties
265+
paimon db alter mydb --remove key1 key2
266+
267+
# Set and remove properties in one command
268+
paimon db alter mydb --set '{"key1": "new_value"}' --remove key2
269+
```
270+
271+
### DB List Tables
272+
273+
List all tables in a database.
274+
275+
```shell
276+
paimon db list-tables mydb
277+
```
278+
279+
Output:
280+
```
281+
orders
282+
products
283+
users
284+
```

paimon-python/pypaimon/catalog/catalog.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,41 @@ def get_database(self, name: str) -> 'Database':
4747
def create_database(self, name: str, ignore_if_exists: bool, properties: Optional[dict] = None):
4848
"""Create a database with properties."""
4949

50+
@abstractmethod
51+
def drop_database(self, name: str, ignore_if_not_exists: bool = False, cascade: bool = False):
52+
"""Drop a database.
53+
54+
Args:
55+
name: Name of the database to drop.
56+
ignore_if_not_exists: If True, do not raise error if database does not exist.
57+
cascade: If True, drop all tables in the database before dropping it.
58+
"""
59+
60+
@abstractmethod
61+
def list_tables(self, database_name: str) -> List[str]:
62+
"""List all table names in the given database.
63+
64+
Args:
65+
database_name: Name of the database.
66+
67+
Returns:
68+
List of table names.
69+
"""
70+
71+
def alter_database(self, name: str, changes: list):
72+
"""Alter database properties.
73+
74+
Args:
75+
name: Name of the database.
76+
changes: List of PropertyChange objects.
77+
78+
Raises:
79+
NotImplementedError: If the catalog does not support alter database.
80+
"""
81+
raise NotImplementedError(
82+
"alter_database is not supported by this catalog."
83+
)
84+
5085
@abstractmethod
5186
def get_table(self, identifier: Union[str, Identifier]) -> 'Table':
5287
"""Get paimon table identified by the given Identifier."""

paimon-python/pypaimon/catalog/filesystem_catalog.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,48 @@ def create_database(self, name: str, ignore_if_exists: bool, properties: Optiona
6565
path = self.get_database_path(name)
6666
self.file_io.mkdirs(path)
6767

68+
def drop_database(self, name: str, ignore_if_not_exists: bool = False, cascade: bool = False):
69+
try:
70+
self.get_database(name)
71+
except DatabaseNotExistException:
72+
if not ignore_if_not_exists:
73+
raise
74+
return
75+
76+
db_path = self.get_database_path(name)
77+
78+
if cascade:
79+
for table_name in self.list_tables(name):
80+
table_path = f"{db_path}/{table_name}"
81+
self.file_io.delete(table_path, True)
82+
83+
# Check if database still has tables
84+
remaining_tables = self.list_tables(name)
85+
if remaining_tables and not cascade:
86+
raise ValueError(
87+
f"Database {name} is not empty. "
88+
f"Use cascade=True to drop all tables first."
89+
)
90+
91+
self.file_io.delete(db_path, True)
92+
93+
def list_tables(self, database_name: str) -> list:
94+
try:
95+
self.get_database(database_name)
96+
except DatabaseNotExistException:
97+
raise
98+
99+
db_path = self.get_database_path(database_name)
100+
statuses = self.file_io.list_status(db_path)
101+
table_names = []
102+
for status in statuses:
103+
import pyarrow.fs as pafs
104+
is_directory = hasattr(status, 'type') and status.type == pafs.FileType.Directory
105+
name = status.base_name if hasattr(status, 'base_name') else ""
106+
if is_directory and name and not name.startswith("."):
107+
table_names.append(name)
108+
return sorted(table_names)
109+
68110
def get_table(self, identifier: Union[str, Identifier]) -> Table:
69111
if not isinstance(identifier, Identifier):
70112
identifier = Identifier.from_string(identifier)

paimon-python/pypaimon/cli/cli.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,13 @@ def main():
107107
from pypaimon.cli.cli_table import add_table_subcommands
108108
add_table_subcommands(table_parser)
109109

110+
# Database commands
111+
db_parser = subparsers.add_parser('db', help='Database operations')
112+
113+
# Import and add database subcommands
114+
from pypaimon.cli.cli_db import add_db_subcommands
115+
add_db_subcommands(db_parser)
116+
110117
args = parser.parse_args()
111118

112119
if args.command is None:

0 commit comments

Comments
 (0)