postgresql_query module: add autocommit parameter (#58704)

* postgresql_query: add autocommit parameter

* postgresql_query: add autocommit parameter, add CI tests

* postgresql_query: add autocommit parameter, add a changelog fragment

* postgresql_query: add autocommit parameter, fix sanity

* postgresql_query: add autocommit parameter, cosmetic fix
This commit is contained in:
Andrey Klychkov 2019-07-04 13:25:51 +03:00 committed by Dag Wieers
parent 7b20535063
commit 6cf722fed6
3 changed files with 122 additions and 2 deletions

View file

@ -0,0 +1,2 @@
minor_changes:
- postgresql_query - add autocommit parameter to support commands that can't be run inside a transaction block (https://github.com/ansible/ansible/pull/58704)

View file

@ -56,6 +56,13 @@ options:
type: str type: str
aliases: aliases:
- login_db - login_db
autocommit:
description:
- Execute in autocommit mode when the query can't be run inside a transaction block
(e.g., VACUUM).
- Mutually exclusive with I(check_mode).
type: bool
version_added: '2.9'
author: author:
- Felix Archambault (@archf) - Felix Archambault (@archf)
- Andrew Klychkov (@Andersson007) - Andrew Klychkov (@Andersson007)
@ -98,6 +105,12 @@ EXAMPLES = r'''
path_to_script: /var/lib/pgsql/test.sql path_to_script: /var/lib/pgsql/test.sql
positional_args: positional_args:
- 1 - 1
- name: Example of using autocommit parameter
postgresql_query:
db: test_db
query: VACUUM
autocommit: yes
''' '''
RETURN = r''' RETURN = r'''
@ -156,6 +169,7 @@ def main():
named_args=dict(type='dict'), named_args=dict(type='dict'),
session_role=dict(type='str'), session_role=dict(type='str'),
path_to_script=dict(type='path'), path_to_script=dict(type='path'),
autocommit=dict(type='bool'),
) )
module = AnsibleModule( module = AnsibleModule(
@ -168,6 +182,10 @@ def main():
positional_args = module.params["positional_args"] positional_args = module.params["positional_args"]
named_args = module.params["named_args"] named_args = module.params["named_args"]
path_to_script = module.params["path_to_script"] path_to_script = module.params["path_to_script"]
autocommit = module.params["autocommit"]
if autocommit and module.check_mode:
module.fail_json(msg="Using autocommit is mutually exclusive with check_mode")
if positional_args and named_args: if positional_args and named_args:
module.fail_json(msg="positional_args and named_args params are mutually exclusive") module.fail_json(msg="positional_args and named_args params are mutually exclusive")
@ -182,7 +200,7 @@ def main():
module.fail_json(msg="Cannot read file '%s' : %s" % (path_to_script, to_native(e))) module.fail_json(msg="Cannot read file '%s' : %s" % (path_to_script, to_native(e)))
conn_params = get_conn_params(module, module.params) conn_params = get_conn_params(module, module.params)
db_connection = connect_to_db(module, conn_params, autocommit=False) db_connection = connect_to_db(module, conn_params, autocommit=autocommit)
cursor = db_connection.cursor(cursor_factory=DictCursor) cursor = db_connection.cursor(cursor_factory=DictCursor)
# Prepare args: # Prepare args:
@ -236,7 +254,8 @@ def main():
if module.check_mode: if module.check_mode:
db_connection.rollback() db_connection.rollback()
else: else:
db_connection.commit() if not autocommit:
db_connection.commit()
kw = dict( kw = dict(
changed=changed, changed=changed,

View file

@ -184,6 +184,53 @@
- result.statusmessage == 'UPDATE 1' - result.statusmessage == 'UPDATE 1'
- result.query_result == {} - result.query_result == {}
# Check:
- name: check the previous update
become_user: "{{ pg_user }}"
become: yes
postgresql_query:
login_user: "{{ pg_user }}"
db: postgres
query: SELECT * FROM test_table WHERE story = 'new' AND id = 3
register: result
- assert:
that:
- result.rowcount == 1
# Test check_mode:
- name: postgresql_query - simple update query in check_mode
become_user: "{{ pg_user }}"
become: yes
postgresql_query:
login_user: "{{ pg_user }}"
db: postgres
query: UPDATE test_table SET story = 'CHECK_MODE' WHERE id = 3
register: result
check_mode: yes
- assert:
that:
- result.changed == true
- result.query == "UPDATE test_table SET story = 'CHECK_MODE' WHERE id = 3"
- result.rowcount == 1
- result.statusmessage == 'UPDATE 1'
- result.query_result == {}
# Check:
- name: check the previous update that nothing has been changed
become_user: "{{ pg_user }}"
become: yes
postgresql_query:
login_user: "{{ pg_user }}"
db: postgres
query: SELECT * FROM test_table WHERE story = 'CHECK_MODE' AND id = 3
register: result
- assert:
that:
- result.rowcount == 0
# Try to update not existing row: # Try to update not existing row:
- name: postgresql_query - try to update not existing row - name: postgresql_query - try to update not existing row
become_user: "{{ pg_user }}" become_user: "{{ pg_user }}"
@ -261,3 +308,55 @@
- result.query == "ALTER TABLE test_table ADD COLUMN foo int" - result.query == "ALTER TABLE test_table ADD COLUMN foo int"
- result.rowcount == 0 - result.rowcount == 0
- result.statusmessage == 'ALTER TABLE' - result.statusmessage == 'ALTER TABLE'
#############################
# Test autocommit parameter #
#############################
- name: postgresql_query - vacuum without autocommit must fail
become_user: "{{ pg_user }}"
become: yes
postgresql_query:
login_user: "{{ pg_user }}"
db: postgres
query: VACUUM
register: result
ignore_errors: yes
- assert:
that:
- result.failed == true
- name: postgresql_query - autocommit in check_mode must fail
become_user: "{{ pg_user }}"
become: yes
postgresql_query:
login_user: "{{ pg_user }}"
db: postgres
query: VACUUM
autocommit: yes
check_mode: yes
register: result
ignore_errors: yes
- assert:
that:
- result.failed == true
- result.msg == "Using autocommit is mutually exclusive with check_mode"
- name: postgresql_query - vacuum with autocommit
become_user: "{{ pg_user }}"
become: yes
postgresql_query:
login_user: "{{ pg_user }}"
db: postgres
query: VACUUM
autocommit: yes
register: result
- assert:
that:
- result.changed == true
- result.query == "VACUUM"
- result.rowcount == 0
- result.statusmessage == 'VACUUM'
- result.query_result == {}