PostgreSQL 学习笔记(四)安装 plpythonu 以使用 Python3 语言编写函数

我不想写 SQL。


1、首先安装 plpython3u 包
PostgreSQL 版本请自行更改,安装之前先前往 pkgs.org 搜索以确定有对应的包。

yum install postgresql12-plpython3

2、为数据库添加扩展
切换到你需要安装 Python3 语言扩展的数据库并执行:

CREATE EXTENSION plpython3u;

3、测试是否安装成功
创建函数:

CREATE OR REPLACE FUNCTION "public"."python3_test" (a integer, b integer)
  RETURNS INT
  LANGUAGE plpython3u
AS $$
  if a > b:
    return a
  return b
$$;

测试一下:

SELECT python3_test(1, 2)
> OK
> 时间: 0.058s
python3_test
2

没有问题。

4、导入 Python3 包和在本数据库执行查询语句
注意:Python3 语句严格使用 4 空格进行缩进!

CREATE OR REPLACE FUNCTION "public"."python3_test"(str text)
  RETURNS INT
	LANGUAGE plpython3u
AS $$
    import random
    # 获取字符串长度
    # 使用 plpy.execute() 直接在本数据库执行 SQL 语句
    select_result = plpy.execute("SELECT CHAR_LENGTH('{}');".format(str))
    str_length = int(select_result[0]["char_length"])
    # 随机数
    random_int = random.randint(0, str_length)
    return random_int
$$;

运行:

SELECT python3_test('1234567890')
> OK
> 时间: 0.033s
python3_test
7

5、第三方 Python 模块的安装和导入
注:这里不修改配置文件,直接用最简单的方法在函数中添加包路径。
第三方模块的安装直接使用 pip3 install 即可,和平时使用 Python3 无异;导入则需要先找到模块安装路径,这里以 requests 为例:

[[email protected] ~]# pip3 show requests
Name: requests
Version: 2.26.0
Summary: Python HTTP for Humans.
Home-page: https://requests.readthedocs.io
Author: Kenneth Reitz
Author-email: [email protected]
License: Apache 2.0
Location: /usr/local/lib/python3.6/site-packages
Requires: urllib3, charset-normalizer, certifi, idna

那么 pip3 默认的安装路径则为:/usr/local/lib/python3.6/site-packages,在函数中进行导入:

CREATE OR REPLACE FUNCTION "public"."python3_test"(url text)
  RETURNS INT
	LANGUAGE plpython3u
AS $$
    import sys
    sys.path.append("/usr/local/lib/python3.6/site-packages/")
    import requests
    # 访问
    response = requests.get(url)
    return response.status_code
$$;

运行:

SELECT python3_test('https://baidu.com')
> OK
> 时间: 0.526s
python3_test
200

6、打印日志和返回表结构的数据

CREATE OR REPLACE FUNCTION "public"."python3_test"(str text)
  RETURNS TABLE(_varchar VARCHAR, _numeric NUMERIC, _boolean BOOLEAN)
	LANGUAGE plpython3u
AS $$
    import sys
    sys.path.append("/usr/local/lib/python3.6/site-packages/")
    # 类
    class return_class():
        def __init__(self, _varchar, _numeric, _boolean):
            self._varchar = _varchar
            self._numeric = _numeric
            self._boolean = _boolean
    # 打印日志
    plpy.debug("debug")
    plpy.log("log")
    plpy.info("info")
    plpy.notice("notice")
    plpy.warning("warning")
    # 返回表结构(在声明了返回表的列名后只要以列为单位生成对象并放入数组返回即可)
    return_classes = []
    a_class = return_class(str, 1.00, True)
    a_class._numeric = 0.01
    return_classes.append(a_class)
    return_classes.append(return_class("bb", 1.23, True))
    return_classes.append(return_class("cc", 3.21, False))
    return return_classes
$$;

运行:

SELECT * FROM python3_test('test_log_table')
> INFO:  info
> NOTICE:  notice
> WARNING:  warning
> OK
> 时间: 0.115s
_varchar _numeric _boolean
test_log_table 0.01 t
bb 1.23 t
cc 3.21 f

结束。