Skip to content

Commit e21e611

Browse files
committed
Switched connection to include port and to use built in module to format URL instead of doing it with interpolation. Added documentation to readme about how to connect to different databases with examples
1 parent 497a914 commit e21e611

File tree

9 files changed

+81
-32
lines changed

9 files changed

+81
-32
lines changed

README.md

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,12 @@ yum install unixODBC-devel
2828
2. Execute an action (example: query)
2929

3030
``` shell
31-
st2 run sql.query host=test_serve.domain.tld username=test_user password=test_password database=test_database database_type=postgresql query="select * from test;"
31+
st2 run sql.query host=test_serve.domain.tld username=test_user password=test_password database=test_database drivername=postgresql query="select * from test;"
3232
```
3333

34-
## Configuration
34+
## Configuration and Connecting to Databases
35+
Connecting to different types of databases is shown below. Connecting to different databases is done in the same manor except with sqlite where all you need to pass is the path to the database in the database option. This is show below. For more information about connections please refer to [SQLAlchemy Connection Docs](https://docs.sqlalchemy.org/en/latest/core/engines.html)
36+
3537
Copy the example configuration in [sql.yaml.example](./sql.yaml.example)
3638
to `/opt/stackstorm/configs/sql.yaml` and edit as required.
3739

@@ -45,13 +47,17 @@ sql:
4547
4648
password: Password
4749
database: TestDatabase
48-
database_type: postgresql
50+
port: 5432
51+
drivername: postgresql
4952
mysql:
5053
host: mysql_db.domain.tld
5154
5255
password: NewPassword
5356
database: TestDatabase
54-
database_type: mysql
57+
drivername: mysql
58+
sqlite:
59+
database: /path/to/db.sqlite
60+
drivername: sqlite
5561
```
5662

5763
Each entry should contain
@@ -60,12 +66,13 @@ Each entry should contain
6066
* ``username`` - Username to authenticate to DB
6167
* ``password`` - Password for DB authentication
6268
* ``database`` - Database to use
63-
* ``database_type`` - The type of database that is being connected to.
69+
* ``port`` - Port to connect to database on. If Default leave blank
70+
* ``drivername`` - The type of database that is being connected to.
6471

6572
When running actions, you can pass in the name of a connection, e.g.
6673
`st2 run sql.query connection="postgresql" query="select * from test;"`
6774

68-
Alternatively, when running an action, you can pass in the host, username, password, database, database_type parameters. These parameters can also be used for overrides if you wish to use the configs as well.
75+
Alternatively, when running an action, you can pass in the host, username, password, database, port, drivername parameters. These parameters can also be used for overrides if you wish to use the configs as well.
6976

7077
**Note** : When modifying the configuration in `/opt/stackstorm/configs/` please remember to tell StackStorm to load these new values by running `st2ctl reload --register-configs`
7178

actions/delete.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
type: string
2828
description: "Optional override of the database in <connection> (required if <connection> is not specified). Database to connect to, to run querys against."
2929
required: false
30-
database_type:
30+
port:
31+
description: "Port to connect to database on. If Default leave blank"
32+
type: integer
33+
required: false
34+
drivername:
3135
type: string
3236
description: "Optional override of the database_type in <connection> (required if <connection> is not specified). The type of database that is being connected to."
3337
enum:

actions/insert.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
type: string
2828
description: "Optional override of the database in <connection> (required if <connection> is not specified). Database to connect to, to run querys against."
2929
required: false
30-
database_type:
30+
port:
31+
description: "Port to connect to database on. If Default leave blank"
32+
type: integer
33+
required: false
34+
drivername:
3135
type: string
3236
description: "Optional override of the database_type in <connection> (required if <connection> is not specified). The type of database that is being connected to."
3337
enum:

actions/insert_bulk.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
type: string
2828
description: "Optional override of the database in <connection> (required if <connection> is not specified). Database to connect to, to run querys against."
2929
required: false
30-
database_type:
30+
port:
31+
description: "Port to connect to database on. If Default leave blank"
32+
type: integer
33+
required: false
34+
drivername:
3135
type: string
3236
description: "Optional override of the database_type in <connection> (required if <connection> is not specified). The type of database that is being connected to."
3337
enum:

actions/lib/base_action.py

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
from st2common.runners.base_action import Action
22
import sqlalchemy
3+
from sqlalchemy.engine.url import URL
34
import decimal
45
import datetime
56

67
# (key, required, default)
7-
CONFIG_CONNECTION_KEYS = [('host', True, ""),
8-
('username', True, ""),
9-
('password', True, ""),
8+
CONFIG_CONNECTION_KEYS = [('host', False, ""),
9+
('username', False, ""),
10+
('password', False, ""),
1011
('database', True, ""),
11-
('database_type', True, "")]
12+
('port', False, None),
13+
('drivername', True, "")]
1214

1315

1416
class BaseAction(Action):
@@ -34,6 +36,9 @@ def get_del_arg(self, key, kwargs_dict, delete=False):
3436
return None
3537

3638
def merge_dicts(self, dicts):
39+
""" Merge Array of dictionaries into 1 single Dictionary
40+
and return.
41+
"""
3742
result = {}
3843
for d in dicts:
3944
if d:
@@ -60,6 +65,11 @@ def row_to_dict(self, row):
6065
return return_dict
6166

6267
def generate_where_clause(self, sql_table, sql_obj, where_dict):
68+
"""Generate WHERE Clause for sql queries with the proper
69+
SQLAlchemy syntax and binding to the proper parameters with
70+
overrides.
71+
Returns Query object
72+
"""
6373
for key in where_dict.keys():
6474
# All column names are reserved. Adding a '_' to the begging of the name
6575
new_key = "_" + key
@@ -73,26 +83,30 @@ def generate_where_clause(self, sql_table, sql_obj, where_dict):
7383
return (sql_obj, where_dict)
7484

7585
def generate_values(self, sql_obj, data_dict):
86+
"""Generate values statement for sql queries with the proper
87+
SQLAlchemy syntax and binding to the proper parameters with
88+
overrides.
89+
Returns Query object
90+
"""
7691
for key in data_dict.keys():
7792
key_dictionary = {key: sqlalchemy.sql.bindparam(key)}
7893
sql_obj = sql_obj.values(**key_dictionary)
7994

8095
return sql_obj
8196

8297
def connect_to_db(self, connection):
83-
database_connection_string = "{0}://{1}:{2}@{3}/{4}".format(connection['database_type'],
84-
connection['username'],
85-
connection['password'],
86-
connection['host'],
87-
connection['database'])
98+
"""Connect to the database and instantiate necessary methods to be used
99+
later.
100+
"""
101+
database_connection_string = URL(**connection)
88102

89103
self.engine = sqlalchemy.create_engine(database_connection_string, echo=False)
90104
self.conn = self.engine.connect()
91105
self.meta = sqlalchemy.MetaData()
92106

93107
return True
94108

95-
def validate_connection(self, connection):
109+
def validate_connection(self, connection, connection_name):
96110
"""Ensures that all required parameters are in the connection. If a
97111
required parameter is missing a KeyError exception is raised.
98112
:param connection: connection to validate
@@ -107,9 +121,9 @@ def validate_connection(self, connection):
107121
if not required:
108122
continue
109123

110-
if connection['connection']:
124+
if connection_name:
111125
raise KeyError("config.yaml mising: sql:{0}:{1}"
112-
.format(connection['connection'], key))
126+
.format(connection_name, key))
113127
else:
114128
raise KeyError("Because the 'connection' action parameter was"
115129
" not specified, the following action parameter"
@@ -132,7 +146,7 @@ def resolve_connection(self, kwargs_dict):
132146
raise KeyError("config.yaml missing connection: sql:{0}"
133147
.format(connection_name))
134148

135-
action_connection = {'connection': connection_name}
149+
action_connection = {}
136150

137151
# Override the keys in creds read in from the config given the
138152
# override parameters from the action itself
@@ -155,6 +169,6 @@ def resolve_connection(self, kwargs_dict):
155169
if key in kwargs_dict:
156170
del kwargs_dict[key]
157171

158-
self.validate_connection(action_connection)
172+
self.validate_connection(action_connection, connection_name)
159173

160174
return action_connection

actions/query.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
type: string
2828
description: "Optional override of the database in <connection> (required if <connection> is not specified). Database to connect to, to run querys against."
2929
required: false
30-
database_type:
30+
port:
31+
description: "Port to connect to database on. If Default leave blank"
32+
type: integer
33+
required: false
34+
drivername:
3135
type: string
3236
description: "Optional override of the database_type in <connection> (required if <connection> is not specified). The type of database that is being connected to."
3337
enum:

actions/update.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,11 @@
2727
type: string
2828
description: "Optional override of the database in <connection> (required if <connection> is not specified). Database to connect to, to run querys against."
2929
required: false
30-
database_type:
30+
port:
31+
description: "Port to connect to database on. If Default leave blank"
32+
type: integer
33+
required: false
34+
drivername:
3135
type: string
3236
description: "Optional override of the database_type in <connection> (required if <connection> is not specified). The type of database that is being connected to."
3337
enum:

config.schema.yaml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,27 @@ connection:
1212
type: object
1313
properties:
1414
host:
15-
description: "Database server to connect to. If not using a default port add that here. ex. host.domain.tld or host.domain.tld:1234"
15+
description: "Database server to connect to. ex. host.domain.tld"
1616
type: string
17-
required: true
17+
required: false
1818
username:
1919
description: "Username for authentication"
2020
type: string
21-
required: true
21+
required: false
2222
password:
2323
description: "Password of the specified username"
2424
type: string
2525
secret: true
26-
required: true
26+
required: false
2727
database:
2828
description: "Database to connect to, to run querys against."
2929
type: string
3030
required: true
31-
database_type:
31+
port:
32+
description: "Port to connect to database on. If Default leave blank"
33+
type: integer
34+
required: false
35+
drivername:
3236
description: "The type of database that is being connected to."
3337
type: string
3438
enum:

sql.yaml.example

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ sql:
55
66
password: Password
77
database: TestDatabase
8-
database_type: postgresql
8+
port: 5432
9+
drivername: postgresql
910
mysql:
1011
host: mysql_db.domain.tld
1112
1213
password: NewPassword
1314
database: TestDatabase
14-
database_type: mysql
15+
drivername: mysql
16+
sqlite:
17+
database: /path/to/db.sqlite
18+
drivername: sqlite

0 commit comments

Comments
 (0)