SQLAlchemy验证SSL连接

时间:2019-03-20 17:59:10

标签: python python-3.x postgresql ssl sqlalchemy

我想验证使用create_engine连接到PostgreSQL数据库时SQLAlchemy建立的SSL连接。例如,如果我有以下Python 3代码:

from sqlalchemy import create_engine

conn_string = "postgresql+psycopg2://myuser:******@someserver:5432/somedb"

conn_args = {
    "sslmode": "verify-full",
    "sslrootcert": "/etc/ssl/certs/ca-certificates.crt",
}

engine = create_engine(conn_string, connect_args=conn_args)

我知道我可以打印engine.__dict__的内容,但是它不包含任何用于连接的SSL设置(TLS版本,密码套件等)的信息:

{
    '_echo': False,
    'dialect': <sqlalchemy.dialects.postgresql.psycopg2.PGDialect_psycopg2 object at 0x7f988a217978>,
    'dispatch': <sqlalchemy.event.base.ConnectionEventsDispatch object at 0x7f988938e788>,
    'engine': Engine(postgresql+psycopg2://myuser:******@someserver:5432/somedb),
    'logger': <Logger sqlalchemy.engine.base.Engine (DEBUG)>,
    'pool': <sqlalchemy.pool.impl.QueuePool object at 0x7f988a238c50>,
    'url': postgresql+psycopg2://myuser:******@someserver:5432/somedb
}

我知道我可以做类似SELECT * FROM pg_stat_ssl;的事情,但是SQLAlchemy引擎是否将这种信息存储为类属性/方法?

谢谢!

3 个答案:

答案 0 :(得分:1)

我不使用postgres,所以希望对您来说如此。

SQLAlchemy接受您在URL中提供的信息,并将其向下传递到也在该URL中指定的基础dbapi库,在您的情况下为psycopg2。

您的engine实例仅在需要时连接到数据库,而sqlalchemy只是将连接信息传递到url中指定的驱动程序,该驱动程序返回sqlalchemy使用的连接。

原谅这是mysql,但对您来说应该基本相同:

>>> engine
Engine(mysql+mysqlconnector://test:***@localhost/test)
>>> conn = engine.connect()
>>> conn
<sqlalchemy.engine.base.Connection object at 0x000001614ACBE2B0>
>>> conn.connection
<sqlalchemy.pool._ConnectionFairy object at 0x000001614BF08630>
>>> conn.connection.connection
<mysql.connector.connection_cext.CMySQLConnection object at 0x000001614AB7E1D0>

调用engine.connect()会返回一个sqlalchemy.engine.base.Connection实例,该实例具有一个connection property,文档字符串说:

  

此Connection管理的基础DB-API连接。

但是,您可以从上面看到它实际上返回了一个sqlalchemy.pool._ConnectionFairy对象,该对象来自它的文档字符串:

  

代理DBAPI连接...

这是连接精灵的__init__()方法,如您所见,它具有一个connection属性,它是实际的基础dbapi连接。

def __init__(self, dbapi_connection, connection_record, echo):
    self.connection = dbapi_connection
    self._connection_record = connection_record
    self._echo = echo

关于dbapi连接对象上可用的信息,取决于特定驱动程序的实现。例如psycopg2连接对象具有info属性:

  

一个ConnectionInfo对象,它公开有关本机libpq的信息   连接。

info对象具有诸如ssl_in_use之类的属性:

  

如果连接使用SSL,则为true,否则为False。

还有ssl_attribute

  

返回有关连接的SSL相关信息。

因此,您不必深入了解实际的数据库连接即可了解实际情况。

此外,如果要确保所有客户端连接均为ssl,则可以始终force them to

答案 1 :(得分:1)

以下是SuperShoot详细说明的内容:

>>> from sqlalchemy import create_engine
>>> db_string = "postgresql+psycopg2://myuser:******@someserver:5432/somedb"
>>> db = create_engine(db_string)
>>> conn = db.connect()
>>> conn.connection.connection.info.ssl_in_use

如果使用SSL,则应返回True。

答案 2 :(得分:0)

如果有人正在寻找 PostgreSQLpg8000,请参阅 pg8000 docs

对于 SSL 默认值,它是:

import sqlalchemy

sqlalchemy.create_engine(url, connect_args={'ssl_context':True})