Repository: getredash/redash

Issue:
PostgreSQL passwords with spaces are not supported
The connection info string on line /opt/redash/current/redash/query_runner/pg.py cant contain spaces, so something like `host=hostname password=my secret password dbname=awesome_db_name user=postgres` will throw the error `OperationalError: missing "=" after "secret" in connection info string`.

Error happens at [pg.py#L117](https://github.com/getredash/redash/blob/fbb81b62d6c79f8e9381ac8973ac34739bfa6b41/redash/query_runner/pg.py#L117), but the connection string is built [pg.py#L87](https://github.com/getredash/redash/blob/fbb81b62d6c79f8e9381ac8973ac34739bfa6b41/redash/query_runner/pg.py#L87).

According the [psycopg2 docs](http://initd.org/psycopg/docs/module.html), you could use:
`conn = psycopg2.connect("dbname=test user=postgres password=secret")`
or 
`conn = psycopg2.connect(database="test", user="postgres", password="secret")`
Currently the first is being used.



Discussion:
As you suggest, we should switch to using the dictionary format of the `connect` method. 

On Monday, I'll try to write up a quick fix and see if there are any other places I see the same error and let you know.

Thanks!

I tried to check things out by switching to a dictionary but I wasn't seeing the logs print out any more.  So I'm not sure what happened, but I've spent all the time I could on it today and ended up just changing the password. 
Sorry.  :)  It's probably a pretty low priority bug, so maybe I'll have some time in a month to come back an check it out again if you'd like me to.

No worries. Whenever you get the chance, it will be appreciated.

Ping on me on chat, when you get to work on it again if you stumble at issues with logging.

I've noticed a related problem with this - if the password field is blank (represented as an empty string in the Redash postgreSQL DB) then Redash seems to try and also confuse the fields, it seemed to mess up the selection of the database.

In my case I'm using SSL client cert authentication so the password isn't used, with a blank field Redash tried to connect to a database with the same name as the username field, rather than the one specified in the dbname

Resolving patch:
diff --git a/redash/query_runner/pg.py b/redash/query_runner/pg.py
--- a/redash/query_runner/pg.py
+++ b/redash/query_runner/pg.py
@@ -1,7 +1,6 @@
 import json
 import logging
 import select
-import sys
 
 import psycopg2
 
@@ -81,15 +80,6 @@ def configuration_schema(cls):
     def type(cls):
         return "pg"
 
-    def __init__(self, configuration):
-        super(PostgreSQL, self).__init__(configuration)
-
-        values = []
-        for k, v in self.configuration.iteritems():
-            values.append("{}={}".format(k, v))
-
-        self.connection_string = " ".join(values)
-
     def _get_definitions(self, schema, query):
         results, error = self.run_query(query, None)
 
@@ -136,7 +126,13 @@ def _get_tables(self, schema):
         return schema.values()
 
     def run_query(self, query, user):
-        connection = psycopg2.connect(self.connection_string, async=True)
+        connection = psycopg2.connect(user=self.configuration.get('user'),
+                                      password=self.configuration.get('password'),
+                                      host=self.configuration.get('host'),
+                                      port=self.configuration.get('port'),
+                                      dbname=self.configuration.get('dbname'),
+                                      async=True)
+
         _wait(connection, timeout=10)
 
         cursor = connection.cursor()


Test patch: