From 515c4a7e2c50319112a3257fb1f0db74683a8853 Mon Sep 17 00:00:00 2001 From: Andrew Klychkov Date: Sat, 11 Jan 2020 17:19:55 +0300 Subject: [PATCH] Bugfix of 65367: postgresql_query doesn't support non-ASCII characters in SQL files with Python3 (#66331) * Bugfix of 65367: postgresql_query doesn't support non-ASCII characters in SQL files with Python3 * add changelog * fix * change changelog fragment, add example --- ...e_to_handle_non_ascii_chars_when_python3.yml | 4 ++++ .../database/postgresql/postgresql_query.py | 17 ++++++++++++++--- .../tasks/postgresql_query_initial.yml | 5 +++-- 3 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/66331-postgresql_query_fix_unable_to_handle_non_ascii_chars_when_python3.yml diff --git a/changelogs/fragments/66331-postgresql_query_fix_unable_to_handle_non_ascii_chars_when_python3.yml b/changelogs/fragments/66331-postgresql_query_fix_unable_to_handle_non_ascii_chars_when_python3.yml new file mode 100644 index 00000000000..1dc1ca61e6c --- /dev/null +++ b/changelogs/fragments/66331-postgresql_query_fix_unable_to_handle_non_ascii_chars_when_python3.yml @@ -0,0 +1,4 @@ +bugfixes: +- postgresql_query - the module doesn't support non-ASCII characters in SQL files with Python3 (https://github.com/ansible/ansible/issues/65367). +minor_changes: +- postgresql_query - add the ``encoding`` parameter (https://github.com/ansible/ansible/issues/65367). diff --git a/lib/ansible/modules/database/postgresql/postgresql_query.py b/lib/ansible/modules/database/postgresql/postgresql_query.py index 65f8ebcf29f..777af2719fc 100644 --- a/lib/ansible/modules/database/postgresql/postgresql_query.py +++ b/lib/ansible/modules/database/postgresql/postgresql_query.py @@ -69,6 +69,12 @@ options: type: bool default: no version_added: '2.9' + encoding: + description: + - Set the client encoding for the current session (e.g. C(UTF-8)). + - The default is the encoding defined by the database. + type: str + version_added: '2.10' seealso: - module: postgresql_db author: @@ -107,12 +113,13 @@ EXAMPLES = r''' db: test_db query: INSERT INTO test_table (id, story) VALUES (2, 'my_long_story') -- name: Run queries from SQL script +- name: Run queries from SQL script using UTF-8 client encoding for session postgresql_query: db: test_db path_to_script: /var/lib/pgsql/test.sql positional_args: - 1 + encoding: UTF-8 - name: Example of using autocommit parameter postgresql_query: @@ -240,6 +247,7 @@ def main(): session_role=dict(type='str'), path_to_script=dict(type='path'), autocommit=dict(type='bool', default=False), + encoding=dict(type='str'), ) module = AnsibleModule( @@ -253,6 +261,7 @@ def main(): named_args = module.params["named_args"] path_to_script = module.params["path_to_script"] autocommit = module.params["autocommit"] + encoding = module.params["encoding"] if autocommit and module.check_mode: module.fail_json(msg="Using autocommit is mutually exclusive with check_mode") @@ -268,13 +277,15 @@ def main(): if path_to_script: try: - with open(path_to_script, 'r') as f: - query = f.read() + with open(path_to_script, 'rb') as f: + query = to_native(f.read()) except Exception as e: module.fail_json(msg="Cannot read file '%s' : %s" % (path_to_script, to_native(e))) conn_params = get_conn_params(module, module.params) db_connection = connect_to_db(module, conn_params, autocommit=autocommit) + if encoding is not None: + db_connection.set_client_encoding(encoding) cursor = db_connection.cursor(cursor_factory=DictCursor) # Prepare args: diff --git a/test/integration/targets/postgresql_query/tasks/postgresql_query_initial.yml b/test/integration/targets/postgresql_query/tasks/postgresql_query_initial.yml index aca07442e20..5a038e706b2 100644 --- a/test/integration/targets/postgresql_query/tasks/postgresql_query_initial.yml +++ b/test/integration/targets/postgresql_query/tasks/postgresql_query_initial.yml @@ -48,7 +48,7 @@ with_items: - SELECT version(); - SELECT story FROM test_table - - WHERE id = %s; + - WHERE id = %s OR story = 'Данные'; when: sql_file_created ############## @@ -84,6 +84,7 @@ path_to_script: '~{{ pg_user }}/test.sql' positional_args: - 1 + encoding: UTF-8 register: result ignore_errors: yes when: sql_file_created @@ -91,7 +92,7 @@ - assert: that: - result is not changed - - result.query == 'SELECT version();\nSELECT story FROM test_table\nWHERE id = 1;\n' + - result.query == "SELECT version();\nSELECT story FROM test_table\nWHERE id = 1 OR story = 'Данные';\n" - result.rowcount == 1 - result.statusmessage == 'SELECT 1' or result.statusmessage == 'SELECT' - result.query_result[0].story == 'first'