-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmssql_query.py
168 lines (145 loc) · 5.15 KB
/
mssql_query.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Copyright © 2017-2018 Mohamed El Morabity
#
# This program is free software: you can redistribute it and/or modify it under the terms of the GNU
# General Public License as published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with this program. If not,
# see <http://www.gnu.org/licenses/>.
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.parsing.convert_bool import BOOLEANS
DOCUMENTATION = '''
---
module: mssql_query
author: Mohamed El Morabity
short_description: Run a SQL query on a Microsoft SQL Server database.
description:
- Run a SQL query on a Microsoft SQL Server database.
options:
login_user:
description:
- The username used to authenticate with.
required: false
default: ''
login_password:
description:
- The password used to authenticate with.
required: false
default: ''
login_host:
description:
- The host running the database.
required: false
default: ''
port:
description:
- The database port to connect to.
type: int
required: false
default: 1433
aliases: ['login_port']
db:
description:
- The name of the database.
required: false
default: ''
query:
description:
- The SQL query to run.
required: True
autocommit:
description:
- Automatically commit the change only if the import succeed. Sometimes it is necessary to use autocommit=true, since some content can't be changed within a transaction.
required: false
default: false
tds_version:
description:
- The TDS protocol version to use.
required: false
default: 7.1
as_dict:
description:
- If true, return results as a list of dictionaries.
type: bool
required: false
default: false
notes:
- Requires the pymssql Python package on the remote host.
requirements: ['pymssql']
'''
EXAMPLES = '''
# Run SQL query
- local_action:
module: mssql_query
db: mydatabase
query: SELECT * FROM myschema.mytable
'''
try:
import pymssql
HAS_LIB = True
except ImportError:
HAS_LIB = False
def run_query(module, db_connection, as_dict):
"""Run a SQL query."""
query = module.params['query']
result = []
try:
cursor = db_connection.cursor(as_dict=as_dict)
cursor.execute(query)
try:
result = cursor.fetchall()
except pymssql.OperationalError as ex:
if 'Statement not executed or executed statement has no resultset' in ex.args:
pass
changed = cursor.rowcount != 0
db_connection.commit()
cursor.close()
except pymssql.ColumnsWithoutNamesError as ex:
# If no column name in result, re-run without as dict
return run_query(module, db_connection, False)
except pymssql.Error as ex:
if ex.args:
module.fail_json(msg='Unable to execute query: {}'.format(ex[1]), errno=ex[0])
module.fail_json(msg='Unable to execute query: {}'.format(ex))
finally:
if db_connection is not None:
db_connection.close()
return (changed, result, cursor.rowcount)
def main():
"""Main execution path."""
module = AnsibleModule(
argument_spec={
'login_host': {'type': 'str', 'default': ''},
'port': {'type': 'int', 'default': 1433, 'aliases': ['login_port']},
'login_user': {'type': 'str', 'default': ''},
'login_password': {'type': 'str', 'default': '', 'no_log': True},
'query': {'required': True, 'type': 'str'},
'db': {'type': 'str', 'default': ''},
'autocommit': {'type': 'bool', 'choices': BOOLEANS, 'default': False},
'tds_version': {'type': 'str', 'default': '7.1'},
'as_dict': {'type': 'bool', 'choices': BOOLEANS, 'default': False},
}
)
if not HAS_LIB:
module.fail_json(msg='pymssql is required for this module')
try:
db_connection = pymssql.connect(host=module.params['login_host'],
port=str(module.params['port']),
user=module.params['login_user'],
password=module.params['login_password'],
database=module.params['db'],
tds_version=module.params['tds_version'])
db_connection.autocommit(module.params['autocommit'])
except pymssql.Error as ex:
module.fail_json(msg='Unable to connect to database: {}'.format(ex))
(changed, result, rowcount) = run_query(module, db_connection,
as_dict=module.params['as_dict'])
module.exit_json(changed=changed, result=result, rowcount=rowcount)
if __name__ == '__main__':
main()