diff --git a/README.md b/README.md index 9b830c1..4d56aca 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ and provides helpers to run (and replay) migrations until it works. * [Command ``upgrade`` (BETA)](#command-upgrade) * [Command ``generate-module-analysis`` (BETA)](#command-generate-module-analysis) * [Command ``estimate-workload`` (BETA)](#command-estimate-workload) + * [Command ``psql``](#command-psql) @@ -365,3 +366,72 @@ the work to do for the migration. renaming or merging of modules) - check that the analysis and migration have been done for the official modules present in odoo/odoo + + + +## Command: ``psql`` + +**Prerequites:** init + +``` +odoo-openupgrade-wizard psql + --database DB_NAME + --command "SQL_REQUEST" +``` + +Execute an SQL Request on the target database. + +**Optional arguments** + +* If no ``database`` is provided, default ``postgres`` database will be used. exemple: + +``` +odoo-openupgrade-wizard psql --command "\l"; +``` +Result: +``` + List of databases + Name | Owner | Encoding | Collate | Ctype | Access privileges +------------+-------+----------+------------+------------+------------------- + postgres | odoo | UTF8 | en_US.utf8 | en_US.utf8 | + template0 | odoo | UTF8 | en_US.utf8 | en_US.utf8 | =c/odoo + + | | | | | odoo=CTc/odoo + template1 | odoo | UTF8 | en_US.utf8 | en_US.utf8 | =c/odoo + + | | | | | odoo=CTc/odoo + test_psql | odoo | UTF8 | en_US.utf8 | en_US.utf8 | + +``` + +* if you execute request that return long result, you can choose to select ``pager`` or ``-no-pager`` + option to display the result via the click function ``echo_via_pager``. + (see : https://click.palletsprojects.com/en/8.1.x/utils/#pager-support) + +Note : Pager is enabled by default. + + +* you can pass extra psql arguments inline. + +``` +odoo-openupgrade-wizard psql + --database=test_psql + --command "select id, name from res_partner where name ilike '%admin%';" + -H +``` +Result: +``` + + + + + + + + + +
idname
3Administrator
+

(1 row)
+

+ +``` + +See all the options here https://www.postgresql.org/docs/current/app-psql.html diff --git a/odoo_openupgrade_wizard/cli/cli.py b/odoo_openupgrade_wizard/cli/cli.py index 9ada813..6677acb 100644 --- a/odoo_openupgrade_wizard/cli/cli.py +++ b/odoo_openupgrade_wizard/cli/cli.py @@ -24,6 +24,7 @@ from odoo_openupgrade_wizard.cli.cli_generate_module_analysis import ( from odoo_openupgrade_wizard.cli.cli_get_code import get_code from odoo_openupgrade_wizard.cli.cli_init import init from odoo_openupgrade_wizard.cli.cli_install_from_csv import install_from_csv +from odoo_openupgrade_wizard.cli.cli_psql import psql from odoo_openupgrade_wizard.cli.cli_pull_submodule import pull_submodule from odoo_openupgrade_wizard.cli.cli_run import run from odoo_openupgrade_wizard.cli.cli_upgrade import upgrade @@ -113,6 +114,7 @@ main.add_command(generate_module_analysis) main.add_command(get_code) main.add_command(init) main.add_command(install_from_csv) +main.add_command(psql) main.add_command(pull_submodule) main.add_command(run) main.add_command(upgrade) diff --git a/odoo_openupgrade_wizard/cli/cli_psql.py b/odoo_openupgrade_wizard/cli/cli_psql.py new file mode 100644 index 0000000..1b4b423 --- /dev/null +++ b/odoo_openupgrade_wizard/cli/cli_psql.py @@ -0,0 +1,21 @@ +import click + +from odoo_openupgrade_wizard.cli.cli_options import database_option +from odoo_openupgrade_wizard.tools.tools_postgres import execute_psql_command + + +@click.command(context_settings={"ignore_unknown_options": True}) +@database_option +@click.option("-c", "--command", "request") +@click.option("--pager/--no-pager", default=True) +@click.argument("psql_args", nargs=-1, type=click.UNPROCESSED) +@click.pass_context +def psql(ctx, request, database, pager, psql_args): + """Run psql in the postgres container. Fill any parameters of psql + as PSQLARGS. + """ + result = execute_psql_command(ctx, request, database, psql_args) + if pager: + click.echo_via_pager(result) + else: + click.echo(result) diff --git a/odoo_openupgrade_wizard/tools/tools_postgres.py b/odoo_openupgrade_wizard/tools/tools_postgres.py index 34da7d3..819a236 100644 --- a/odoo_openupgrade_wizard/tools/tools_postgres.py +++ b/odoo_openupgrade_wizard/tools/tools_postgres.py @@ -104,21 +104,9 @@ def execute_sql_file(ctx, database, sql_file): def execute_sql_request(ctx, request, database="postgres"): - container = get_postgres_container(ctx) - command = ( - "psql" - " --username=odoo" - " --dbname={database}" - " --tuples-only" - ' --command "{request}"' - ).format(database=database, request=request) - logger.debug( - "Executing the following command in postgres container" - " on database %s \n %s" % (database, request) - ) - docker_result = exec_container(container, command) - - lines = docker_result.output.decode("utf-8").split("\n") + psql_args = ("--tuples-only",) + output = execute_psql_command(ctx, request, database, psql_args) + lines = output.split("\n") result = [] for line in lines: if not line: @@ -127,6 +115,26 @@ def execute_sql_request(ctx, request, database="postgres"): return result +def execute_psql_command( + ctx, request: str, database: str = None, psql_args: tuple = () +): + """Execute psql request in postgres container with psql_args on database""" + container = get_postgres_container(ctx) + command = ( + "psql" + " --username=odoo" + f" --dbname={database or 'postgres'}" + f' --command "{request}"' + f" {' '.join(psql_args)}" + ) + logger.debug( + "Executing the following command in postgres container\n" + "%s" % (command) + ) + docker_result = exec_container(container, command) + return docker_result.output.decode("utf-8") + + def ensure_database(ctx, database: str, state="present"): """ - Connect to postgres container. diff --git a/tests/cli_30_psql_test.py b/tests/cli_30_psql_test.py new file mode 100644 index 0000000..bc32b60 --- /dev/null +++ b/tests/cli_30_psql_test.py @@ -0,0 +1,73 @@ +from pytest import raises + +from odoo_openupgrade_wizard.tools.tools_postgres import ( + ensure_database, + execute_psql_command, +) + +from . import ( + build_ctx_from_config_file, + cli_runner_invoke, + move_to_test_folder, +) + + +def test_cli_psql(): + move_to_test_folder() + ctx = build_ctx_from_config_file() + + db_name = "database_test_cli___psql" + ensure_database(ctx, db_name, state="absent") + + # initialize database + cli_runner_invoke( + [ + "--log-level=DEBUG", + "run", + "--step=1", + "--database=%s" % db_name, + "--init-modules=base", + "--stop-after-init", + ], + ) + + # Test requests from lib + request = ( + "SELECT name" + " FROM ir_module_module" + " WHERE state ='installed'" + " AND name='base';" + ) + output = execute_psql_command( + ctx, + request, + database=db_name, + psql_args=("--tuples-only",), + ) + assert output.strip() == "base" + + # test via cli ok + cli_runner_invoke( + [ + "--log-level=DEBUG", + "psql", + "--database=%s" % db_name, + '--command "%s"' % request, + "--no-pager", + "--tuples-only", + ], + ) + + # test that cli fails with wrong parameters + with raises(Exception): + cli_runner_invoke( + [ + "--log-level=DEBUG", + "psql", + "--database=%s" % db_name, + '--command "%s"' % request, + "--no-pager", + "--tuples-only", + "---unkwon-argument", + ], + )