Skip to content

Commit a298721

Browse files
committed
added sql_shell command
1 parent 77afec4 commit a298721

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

piccolo/apps/sql_shell/__init__.py

Whitespace-only changes.

piccolo/apps/sql_shell/commands/__init__.py

Whitespace-only changes.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import os
2+
import signal
3+
import subprocess
4+
import typing as t
5+
6+
from piccolo.engine.postgres import PostgresEngine
7+
from piccolo.engine.sqlite import SQLiteEngine
8+
from piccolo.engine.finder import engine_finder
9+
10+
if t.TYPE_CHECKING:
11+
from piccolo.engine.base import Engine
12+
13+
14+
def run():
15+
"""
16+
Launch the SQL shell for the configured engine. For Postgres
17+
this will be psql, and for SQLite it will be sqlite3.
18+
"""
19+
engine: t.Optional[Engine] = engine_finder()
20+
21+
if engine is None:
22+
raise ValueError(
23+
"Unable to find the engine - make sure piccolo_conf is on the "
24+
"path."
25+
)
26+
27+
# Heavily inspired by Django's dbshell command
28+
if isinstance(engine, PostgresEngine):
29+
engine: PostgresEngine = engine
30+
31+
args = ["psql"]
32+
33+
host = engine.config.get("host")
34+
port = engine.config.get("port")
35+
user = engine.config.get("user")
36+
password = engine.config.get("password")
37+
database = engine.config.get("database")
38+
39+
if user:
40+
args += ["-U", user]
41+
if host:
42+
args += ["-h", host]
43+
if port:
44+
args += ["-p", str(port)]
45+
args += [database]
46+
47+
sigint_handler = signal.getsignal(signal.SIGINT)
48+
subprocess_env = os.environ.copy()
49+
if password:
50+
subprocess_env["PGPASSWORD"] = str(password)
51+
try:
52+
# Allow SIGINT to pass to psql to abort queries.
53+
signal.signal(signal.SIGINT, signal.SIG_IGN)
54+
print("Enter \\q to exit")
55+
subprocess.run(args, check=True, env=subprocess_env)
56+
finally:
57+
# Restore the original SIGINT handler.
58+
signal.signal(signal.SIGINT, sigint_handler)
59+
60+
elif isinstance(engine, SQLiteEngine):
61+
engine: SQLiteEngine = engine
62+
print("Enter .quit to exit")
63+
subprocess.run(
64+
["sqlite3", engine.connection_kwargs.get("database")], check=True
65+
)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from piccolo.conf.apps import AppConfig
2+
from .commands.run import run
3+
4+
5+
APP_CONFIG = AppConfig(
6+
app_name="sql_shell", migrations_folder_path="", commands=[run]
7+
)

piccolo/main.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from piccolo.apps.playground.piccolo_app import APP_CONFIG as playground_config
1212
from piccolo.apps.project.piccolo_app import APP_CONFIG as project_config
1313
from piccolo.apps.shell.piccolo_app import APP_CONFIG as shell_config
14+
from piccolo.apps.sql_shell.piccolo_app import APP_CONFIG as sql_shell_config
1415
from piccolo.apps.user.piccolo_app import APP_CONFIG as user_config
1516

1617

@@ -53,6 +54,7 @@ def main():
5354
playground_config,
5455
project_config,
5556
shell_config,
57+
sql_shell_config,
5658
user_config,
5759
]:
5860
for command in _app_config.commands:

0 commit comments

Comments
 (0)