Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

postgresql_query: add query_all_results ret value #886

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/886-postgresql_query_add_ret_vals.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- postgresql_query - add ``query_list`` and ``query_all_results`` return values (https://github.com/ansible-collections/community.general/issues/838).
112 changes: 76 additions & 36 deletions plugins/modules/database/postgresql/postgresql_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@
type: dict
path_to_script:
description:
- Path to SQL script on the remote host.
- Returns result of the last query in the script.
- Path to an SQL script on the target machine.
Andersson007 marked this conversation as resolved.
Show resolved Hide resolved
- If the script contains several queries, they must be semicolon-separated.
- Mutually exclusive with I(query).
type: path
session_role:
Expand Down Expand Up @@ -175,23 +175,45 @@

RETURN = r'''
query:
description: Query that was tried to be executed.
description:
- Executed query.
- When reading several queries from a file, it contains the last one.
Andersson007 marked this conversation as resolved.
Show resolved Hide resolved
returned: always
type: str
sample: 'SELECT * FROM bar'
statusmessage:
description: Attribute containing the message returned by the command.
description:
- Attribute containing the message returned by the command.
- When reading several queries from a file, it contains a message of the last one.
returned: always
type: str
sample: 'INSERT 0 1'
query_result:
description:
- List of dictionaries in column:value form representing returned rows.
returned: changed
- When running queries from a file, returns result of the last query.
returned: always
type: list
elements: dict
sample: [{"Column": "Value1"},{"Column": "Value2"}]
query_list:
description:
- List of executed queries.
Useful when reading several queries from a file.
returned: always
type: list
elements: str
sample: ['SELECT * FROM foo', 'SELECT * FROM bar']
query_all_results:
description:
- List containing results of all queries executed (one sublist for every query).
Useful when reading several queries from a file.
returned: always
type: list
elements: list
sample: [[{"Column": "Value1"},{"Column": "Value2"}], [{"Column": "Value1"},{"Column": "Value2"}]]
rowcount:
description: Number of affected rows.
description: Total number of produced or affected rows.
Andersson007 marked this conversation as resolved.
Show resolved Hide resolved
returned: changed
type: int
sample: 5
Expand Down Expand Up @@ -318,12 +340,19 @@ def main():
elif named_args:
named_args = convert_elements_to_pg_arrays(named_args)

query_list = []
if path_to_script:
try:
with open(path_to_script, 'rb') as f:
query = to_native(f.read())
if ';' in query:
query_list = [q for q in query.split(';') if q != '\n']
else:
query_list.append(query)
except Exception as e:
module.fail_json(msg="Cannot read file '%s' : %s" % (path_to_script, to_native(e)))
else:
query_list.append(query)

conn_params = get_conn_params(module, module.params)
db_connection = connect_to_db(module, conn_params, autocommit=autocommit)
Expand All @@ -345,45 +374,54 @@ def main():
# Set defaults:
changed = False

query_all_results = []
rowcount = 0
statusmessage = ''

# Execute query:
try:
cursor.execute(query, arguments)
except Exception as e:
if not autocommit:
db_connection.rollback()
for query in query_list:
try:
cursor.execute(query, arguments)
statusmessage = cursor.statusmessage
if cursor.rowcount > 0:
rowcount += cursor.rowcount

cursor.close()
db_connection.close()
module.fail_json(msg="Cannot execute SQL '%s' %s: %s" % (query, arguments, to_native(e)))
try:
query_result = [dict(row) for row in cursor.fetchall()]

statusmessage = cursor.statusmessage
rowcount = cursor.rowcount
except Psycopg2ProgrammingError as e:
if to_native(e) == 'no results to fetch':
query_result = {}

try:
query_result = [dict(row) for row in cursor.fetchall()]
except Psycopg2ProgrammingError as e:
if to_native(e) == 'no results to fetch':
query_result = {}
except Exception as e:
module.fail_json(msg="Cannot fetch rows from cursor: %s" % to_native(e))

except Exception as e:
module.fail_json(msg="Cannot fetch rows from cursor: %s" % to_native(e))
query_all_results.append(query_result)

if 'SELECT' not in statusmessage:
if 'UPDATE' in statusmessage or 'INSERT' in statusmessage or 'DELETE' in statusmessage:
s = statusmessage.split()
if len(s) == 3:
if statusmessage.split()[2] != '0':
changed = True
if 'SELECT' not in statusmessage:
if 'UPDATE' in statusmessage or 'INSERT' in statusmessage or 'DELETE' in statusmessage:
s = statusmessage.split()
if len(s) == 3:
if s[2] != '0':
changed = True

elif len(s) == 2:
if s[1] != '0':
changed = True

elif len(s) == 2:
if statusmessage.split()[1] != '0':
else:
changed = True

else:
changed = True

else:
changed = True
except Exception as e:
if not autocommit:
db_connection.rollback()

else:
changed = True
cursor.close()
db_connection.close()
module.fail_json(msg="Cannot execute SQL '%s' %s: %s, query list: %s" % (query, arguments, to_native(e), query_list))

if module.check_mode:
db_connection.rollback()
Expand All @@ -394,9 +432,11 @@ def main():
kw = dict(
changed=changed,
query=cursor.query,
query_list=query_list,
statusmessage=statusmessage,
query_result=query_result,
rowcount=rowcount if rowcount >= 0 else 0,
query_all_results=query_all_results,
rowcount=rowcount,
)

cursor.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@
that:
- result is changed
- result.query == 'ANALYZE test_table'
- result.query_list == ['ANALYZE test_table']
- result.rowcount == 0
- result.statusmessage == 'ANALYZE'
- result.query_result == {}
- result.query_all_results == [{}]

- name: postgresql_query - run queries from SQL script
become_user: '{{ pg_user }}'
Expand All @@ -79,10 +81,12 @@
- assert:
that:
- result is not changed
- 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 == "\nSELECT story FROM test_table\nWHERE id = 1 OR story = 'Данные'"
- result.query_result[0].story == 'first'
- result.query_all_results[0][0].version is search('PostgreSQL')
- result.query_all_results[1][0].story == 'first'
- result.rowcount == 2
- result.statusmessage == 'SELECT 1' or result.statusmessage == 'SELECT'
when: sql_file_created

- name: postgresql_query - simple select query to test_table
Expand Down