https://github.com/digicoop/postgres-proto
Postgres-Proto
用于实现使用 PostgreSQL 协议进行通信的套接字服务器的实用工具。
为您的应用程序添加 PostgreSQL 协议支持,即刻获得与数百个现有应用程序的兼容性(例如:商业智能工具、报告工具、无代码应用程序制作器等)。
包含一个简单且宽容的 SQL 解析器,用于实现自定义 SQL 语句。
功能:
- 超级容易实现自定义语句的处理
- 身份验证
- SSL
- 信息模式发现
- 预处理语句的处理
- 确保与大多数在启动时执行某些查询的工具的最低兼容性
- 高水平的可定制性和扩展能力
警告:这不是协议的完整实现( notably 缺少 COPY 功能)。但是,它提供了足够的功能来确保与许多客户端的兼容性。
示例
from postgres_proto.socket_handler import PostgresRequestHandler
from postgres_proto.flow import PostgresError
DATABASE = {'table1': [{'id': 1, 'title': 'hello world'}]}
class MyRequestHandler(PostgresRequestHandler):
def query_tables(self, stmt_info):
rows = DATABASE.get(stmt_info.tables[0].name, [])
return rows, rows[0].keys()
def list_tables(self):
return DATABASE.keys()
def describe_table(self, table_name):
return DATABASE.get(table_name, [[]])[0].keys()
然后使用此请求处理程序启动服务器:$ python -m postgres_proto.server your_file.MyRequestHandler。
(有关更多选项,请使用 python -m postgres_proto.server --help)
最后使用任何 postgres 客户端进行连接:
$ psql -h localhost -p 55432
> select * from information_schema.tables;
> select * from information_schema.columns where table_name = 'table1';
> select * from table1;
(注意默认端口:55432)
查看示例文件夹以获取更多信息!
架构
协议处理独立于套接字实现。
- 读取和写入协议消息在
postgres_proto.stream中实现 - 协议流程在
postgres_proto.flow中实现(确保读写消息的正确顺序)
在您自己的类中使用 PostgresServerFlowMixin 并覆盖标记为未实现的方法。
您还可以覆盖一些加密和身份验证方法以添加对这些功能的支持。
postgres_proto.socket_handler.base.BasePostgresStreamRequestHandler 是一个使用 PostgresServerFlowMixin
并提供 SSL 支持的套接字请求处理程序。由您来覆盖其他协议流程方法。
postgres_proto.socket_handler.PostgresRequestHandler 是一个即用型套接字请求处理程序,您可以专注于处理 SQL 语句。
它使用各种实用程序 mixin 来支持关于信息模式或特定 postgres 表的查询。在大多数情况下,您希望
继承这个类,因为它将确保与许多现有客户端的兼容性。
子类化 PostgresRequestHandler
PostgresRequestHandler 覆盖了 PostgresServerFlowMixin 中的 execute_query() 方法以提供 SQL 语句处理。
它与 QueryInformationSchemaMixin 和 QueryPostgresBuiltinsMixin 集成,以确保正确处理这些表。
当调用 execute_query() 时,SQL 查询使用 postgres_proto.sql.parser.parse_sql() 进行解析,该解析器提供 stmt_type 和 stmt_info。
有关更多详细信息,请参见 parse_sql()。
解析后,将调用与语句类型关联的处理程序。
SELECT 语句已被处理。当收到 SELECT 语句时,将调用 query_tables()。您必须覆盖此函数。
query_tables() 必须返回一个元组,其中第一项是字典列表(行),第二项是名称列表(列名)。
对于其他语句类型,向您的请求处理程序类添加一个方法,并使用 postgres_proto.socket_handler.stmt_handler 进行装饰。
您的处理程序将接收 stmt_info 对象。
from postgres_proto.socket_handler import PostgresRequestHandler, stmt_handler
class MyRequestHandler(PostgresRequestHandler):
def query_tables(self, stmt_info):
return [], []
@stmt_handler('INSERT')
def handle_insert(self, stmt_info):
return None, None # 无结果
如果语句类型没有处理程序,除非它列在 PostgresRequestHandler.ignore_missing_statement_types 属性中,否则将触发错误。
错误处理
引发类型为 postgres_proto.flow.PostgresError 的异常,以便将它们作为错误传达给客户端。任何其他异常类型都不会被拦截,并将导致套接字终止。
您可以使用 postgres_proto.flow.catch_all_as_postgres_error_context() 来创建一个上下文,其中所有异常都被包装为 PostgresError。
from postgres_proto.flow import catch_all_as_postgres_error_context
with catch_all_as_postgres_error_context():
raise Exception('my error')
处理信息模式查询
信息模式查询可以使用 postgres_proto.socket_handler.info_schema.QueryInformationSchemaMixin 处理,PostgresRequestHandler 已经使用了它。
覆盖以下方法以提供模式信息:
list_tables(): 返回表名列表describe_table(table_name): 返回指定表的列名列表
处理预处理语句
预处理语句可以使用 postgres_proto.socket_handler.prepared_stmts.PostgresPreparedStatementsRequestHandlerMixin 处理,PostgresRequestHandler 已经使用了它。
这提供了基本处理,并将预处理语句视为通过 execute_query() 执行的普通查询。
为了处理描述请求,这些语句可能在实际执行命令之前执行并保存其结果。这允许使用 execute_query() 的结果(即列列表)发回行描述数据。因此,预处理语句的处理是完全透明的。
启用 SSL 支持
当套接字服务器对象上存在 ssl_context 属性时,BasePostgresStreamRequestHandler 支持 SSL。
您可以使用 postgres_proto.server.create_ssl_context() 轻松创建 ssl 上下文。您将需要一个私钥和证书。自签名可以正常工作。
使用 CLI 时,分别使用 --ssl-key 和 --ssl-cert 提供密钥和证书。

1548

被折叠的 条评论
为什么被折叠?



