diff --git a/src/datajoint/__init__.py b/src/datajoint/__init__.py index 7e07977f3..7f809487d 100644 --- a/src/datajoint/__init__.py +++ b/src/datajoint/__init__.py @@ -39,7 +39,6 @@ "Top", "U", "Diagram", - "kill", "MatCell", "MatStruct", # Codec API @@ -94,8 +93,6 @@ # Diagram imports networkx and matplotlib "Diagram": (".diagram", "Diagram"), "diagram": (".diagram", None), # Return the module itself - # kill imports pymysql via connection - "kill": (".admin", "kill"), # cli imports click "cli": (".cli", "cli"), } diff --git a/src/datajoint/admin.py b/src/datajoint/admin.py deleted file mode 100644 index 275e9a823..000000000 --- a/src/datajoint/admin.py +++ /dev/null @@ -1,101 +0,0 @@ -import logging - -import pymysql - -from .connection import conn - -logger = logging.getLogger(__name__.split(".")[0]) - - -def kill(restriction=None, connection=None, order_by=None): - """ - View and kill database connections interactively. - - Displays a list of active connections and prompts for connections to kill. - - Parameters - ---------- - restriction : str, optional - SQL WHERE clause to filter connections. Can use any attribute from - information_schema.processlist: ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO. - connection : Connection, optional - A datajoint.Connection object. Defaults to datajoint.conn(). - order_by : str or list[str], optional - Attribute(s) to order results by. Defaults to 'id'. - - Examples - -------- - >>> dj.kill('HOST LIKE "%compute%"') # List connections from hosts containing "compute" - >>> dj.kill('TIME > 600') # List connections idle for more than 10 minutes - """ - - if connection is None: - connection = conn() - - if order_by is not None and not isinstance(order_by, str): - order_by = ",".join(order_by) - - query = ( - "SELECT * FROM information_schema.processlist WHERE id <> CONNECTION_ID()" - + ("" if restriction is None else " AND (%s)" % restriction) - + (" ORDER BY %s" % (order_by or "id")) - ) - - while True: - print(" ID USER HOST STATE TIME INFO") - print("+--+ +----------+ +-----------+ +-----------+ +-----+") - cur = ({k.lower(): v for k, v in elem.items()} for elem in connection.query(query, as_dict=True)) - for process in cur: - try: - print("{id:>4d} {user:<12s} {host:<12s} {state:<12s} {time:>7d} {info}".format(**process)) - except TypeError: - print(process) - response = input('process to kill or "q" to quit > ') - if response == "q": - break - if response: - try: - pid = int(response) - except ValueError: - pass # ignore non-numeric input - else: - try: - connection.query("kill %d" % pid) - except pymysql.err.InternalError: - logger.warn("Process not found") - - -def kill_quick(restriction=None, connection=None): - """ - Kill database connections without prompting. - - Parameters - ---------- - restriction : str, optional - SQL WHERE clause to filter connections. Can use any attribute from - information_schema.processlist: ID, USER, HOST, DB, COMMAND, TIME, STATE, INFO. - connection : Connection, optional - A datajoint.Connection object. Defaults to datajoint.conn(). - - Returns - ------- - int - Number of terminated connections. - - Examples - -------- - >>> dj.kill_quick('HOST LIKE "%compute%"') # Kill connections from hosts with "compute" - """ - if connection is None: - connection = conn() - - query = "SELECT * FROM information_schema.processlist WHERE id <> CONNECTION_ID()" + ( - "" if restriction is None else " AND (%s)" % restriction - ) - - cur = ({k.lower(): v for k, v in elem.items()} for elem in connection.query(query, as_dict=True)) - nkill = 0 - for process in cur: - connection.query("kill %d" % process["id"]) - nkill += 1 - return nkill diff --git a/src/datajoint/table.py b/src/datajoint/table.py index 8c672f41e..16cb51b6d 100644 --- a/src/datajoint/table.py +++ b/src/datajoint/table.py @@ -50,12 +50,6 @@ ) -class _RenameMap(tuple): - """for internal use""" - - pass - - @dataclass class ValidationResult: """ diff --git a/tests/unit/test_lazy_imports.py b/tests/unit/test_lazy_imports.py index f5142516e..a87412151 100644 --- a/tests/unit/test_lazy_imports.py +++ b/tests/unit/test_lazy_imports.py @@ -27,25 +27,6 @@ def test_lazy_diagram_import(): assert Diagram.__name__ == "Diagram" -def test_lazy_admin_import(): - """Admin module should not be loaded until dj.kill is accessed.""" - # Remove datajoint from sys.modules to get fresh import - modules_to_remove = [key for key in sys.modules if key.startswith("datajoint")] - for mod in modules_to_remove: - del sys.modules[mod] - - # Import datajoint - import datajoint as dj - - # Admin module should not be loaded yet - assert "datajoint.admin" not in sys.modules, "admin module loaded eagerly" - - # Access kill - should trigger lazy load - kill = dj.kill - assert "datajoint.admin" in sys.modules, "admin module not loaded after access" - assert callable(kill) - - def test_lazy_cli_import(): """CLI module should not be loaded until dj.cli is accessed.""" # Remove datajoint from sys.modules to get fresh import @@ -103,5 +84,4 @@ def test_core_imports_available(): # Heavy modules should still not be loaded assert "datajoint.diagram" not in sys.modules - assert "datajoint.admin" not in sys.modules assert "datajoint.cli" not in sys.modules