--- /dev/null
+.. change::
+ :tags: feature, postgresql
+ :tickets: 4562
+
+ Added support for parameter-less connection URLs for the psycopg2 dialect,
+ meaning, the URL can be passed to :func:`.create_engine` as
+ ``"postgresql+psycopg2://"`` with no additional arguments to indicate an
+ empty DSN passed to libpq, which indicates to connect to "localhost" with
+ no username, password, or database given. Pull request courtesy Julian
+ Mehnle.
\ No newline at end of file
`PQconnectdbParams \
<http://www.postgresql.org/docs/9.1/static/libpq-connect.html#LIBPQ-PQCONNECTDBPARAMS>`_
+Empty DSN Connections / Environment Variable Connections
+---------------------------------------------------------
+
+The psycopg2 DBAPI can connect to PostgreSQL by passing an empty DSN to the
+libpq client library, which by default indicates to connect to a localhost
+PostgreSQL database that is open for "trust" connections. This behavior can be
+further tailored using a particular set of environment variables which are
+prefixed with ``PG_...``, which are consumed by ``libpq`` to take the place of
+any or all elements of the connection string.
+
+For this form, the URL can be passed without any elements other than the
+initial scheme::
+
+ engine = create_engine('postgresql+psycopg2://')
+
+In the above form, a blank "dsn" string is passed to the ``psycopg2.connect()``
+function which in turn represents an empty DSN passed to libpq.
+
+.. versionadded:: 1.3.2 support for parameter-less connections with psycopg2.
+
+.. seealso::
+
+ `Environment Variables\
+ <https://www.postgresql.org/docs/current/libpq-envars.html>`_ -
+ PostgreSQL documentation on how to use ``PG_...``
+ environment variables for connections.
+
.. _psycopg2_execution_options:
Per-Statement/Connection Execution Options
def create_connect_args(self, url):
opts = url.translate_connect_args(username="user")
- if "port" in opts:
- opts["port"] = int(opts["port"])
- opts.update(url.query)
- return ([], opts)
+ if opts:
+ if "port" in opts:
+ opts["port"] = int(opts["port"])
+ opts.update(url.query)
+ # send individual dbname, user, password, host, port
+ # parameters to psycopg2.connect()
+ return ([], opts)
+ else:
+ # send a blank string for "dsn" to psycopg2.connect()
+ return ([''], opts)
def is_disconnect(self, e, connection, cursor):
if isinstance(e, self.dbapi.Error):
from sqlalchemy import text
from sqlalchemy import TypeDecorator
from sqlalchemy.dialects.postgresql import base as postgresql
+from sqlalchemy.dialects.postgresql import psycopg2 as psycopg2_dialect
from sqlalchemy.engine import engine_from_config
from sqlalchemy.engine import url
from sqlalchemy.testing import engines
e = engine_from_config(config, _initialize=False)
eq_(e.dialect.use_native_unicode, True)
+ def test_psycopg2_empty_connection_string(self):
+ dialect = psycopg2_dialect.dialect()
+ u = url.make_url("postgresql://")
+ cargs, cparams = dialect.create_connect_args(u)
+ eq_(cargs, [''])
+ eq_(cparams, {})
+
+ def test_psycopg2_nonempty_connection_string(self):
+ dialect = psycopg2_dialect.dialect()
+ u = url.make_url("postgresql://host")
+ cargs, cparams = dialect.create_connect_args(u)
+ eq_(cargs, [])
+ eq_(cparams, {"host": "host"})
+
class BatchInsertsTest(fixtures.TablesTest):
__only_on__ = "postgresql+psycopg2"