在我上一篇机器学习博客PostgreSQL 和机器学习中:
https://www.enterprisedb.com/blog/postgresql-and-machine-learning
我研究了为什么我们可能希望将机器学习集成到我们的数据库中,并展示了使用Apache MADlib 和 Tensorflow分析波士顿住房数据集的示例:
https://madlib.apache.org/
https://www.tensorflow.org/
https://www.cs.toronto.edu/~delve/data/boston/bostonDetail.html
在这个博客中,我们将更深入地研究我编写的使用 Tensorflow 执行此分析的代码。虽然 MADlib 对于在你的数据库中构建智能分析当然很有用,但使用 Tensorflow 可以说更有趣,因为我们可以使用 pl/python3 轻松构建我们想要的任何东西,因为我们可以访问 Tensorflow(或PyTorch:https://pytorch.org/ )的所有细节或scikit-learn: https://scikit-learn.org/等)以及几乎整个 Python 包生态系统,其中包括非常方便的库,例如Pandas:https://pandas.pydata.org/ 和Numpy:https://numpy.org/。
在第 1 部分中,我们将了解如何设置所有内容以及在 PostgreSQL 中使用 pl/python3 的一些基础知识。
安装 PostgreSQL 和 pl/python3
首先,您需要安装 PostgreSQL 并安装 pl/python3 过程语言扩展。在 Windows 或 macOS 上,使用 EDB 安装程序安装 PostgreSQL,您可以通过PostgreSQL 网站 获得:https://www.postgresql.org/download/。然后,您可以使用 StackBuilder 实用程序来安装 EDB LanguagePack,它将添加所需的 Python 支持。
在 Linux 上安装 PostgreSQL 的说明也可以在上面的链接中找到。在下面的示例中,我将使用 Ubuntu 20.04。
dpage@ubuntu:~$ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'[sudo] password for dpage:dpage@ubuntu:~$ wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -OKdpage@ubuntu:~$ sudo apt-get updateHit:1 http://us.archive.ubuntu.com/ubuntu focal InReleaseGet:2 http://security.ubuntu.com/ubuntu focal-security InRelease [109 kB]Get:3 http://us.archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]Get:4 http://apt.postgresql.org/pub/repos/apt focal-pgdg InRelease [81.6 kB]Get:5 http://apt.postgresql.org/pub/repos/apt focal-pgdg/main amd64 Packages [188 kB]...dpage@ubuntu:~$ sudo apt-get -y install postgresql-13 postgresql-plpython3-13Reading package lists... DoneBuilding dependency treeReading state information... DoneThe following additional packages will be installed:libpq5 pgdg-keyring postgresql-client-13 postgresql-client-common postgresql-common sysstat...dpage@ubuntu:~$
值得注意的是,官方的 Tensorflow 包支持在 Linux 和 Windows 上使用 GPU,但不支持 macOS。对于简单的回归分析,这应该不是问题,但对于更复杂的任务,它可能会在训练时导致性能问题。可以将分布式节点、GPU 或 TPU 与 Tensorflow 一起使用,因此如果您的数据库服务器上没有 GPU,或者您在 macOS 上运行,您可能会考虑将工作卸载到具有 GPU 的外部节点。有关更多信息,请参阅Tensorflow 文档。
https://www.tensorflow.org/guide/distributed_training
设置 Python 环境
现在,我们需要备Python 环境。在 Windows 或 macOS 上,使用 LanguagePack 安装中包含的 pip 实用程序的完整路径来确保将包安装到正确的 Python 环境中。在 Linux 上,使用系统 Python 环境。根据您的发行版,您可能需要使用pip3而不是 pip 来确保您安装的是 Python 3 而不是 Python 2 的包:
dpage@ubuntu:~$ sudo pip3 install tensorflow pandas matplotlib seabornCollecting tensorflowDownloading tensorflow-2.4.1-cp38-cp38-manylinux2010_x86_64.whl (394.4 MB)|████████████████████████████████| 394.4 MB 25 kB/sCollecting numpyDownloading numpy-1.20.1-cp38-cp38-manylinux2010_x86_64.whl (15.4 MB)|████████████████████████████████| 15.4 MB 1.3 MB/s...dpage@ubuntu:~$
请注意,我没有在这里明确安装numpy库;将自动安装兼容版本,因为 Tensorflow 依赖于它。我还安装了一些额外的库:
pandas;一个强大的数据分析库
matplotlib; 用于绘制图表以进行数据分析
seaborn;与 matplotlib 配合使用,提供各种数据可视化选项
现在一切都安装好了,我们可以在 PostgreSQL 中运行一个快速测试:
dpage@ubuntu:~$ sudo su - postgrespostgres@ubuntu:~$ psql postgrespsql (13.2 (Ubuntu 13.2-1.pgdg20.04+1))Type "help" for help.postgres=# CREATE DATABASE tf;CREATE DATABASEpostgres=# \connect tfYou are now connected to database "tf" as user "postgres".tf=# CREATE LANGUAGE plpython3u;CREATE EXTENSIONtf=# CREATE FUNCTION tf_version()tf-# RETURNS texttf-# AS $$tf$# import tensorflow as tftf$# return tf.__version__tf$# $$tf-# LANGUAGE plpython3u;CREATE FUNCTIONtf=# SELECT tf_version();test_tf---------2.4.1(1 row)tf=#
我们在这里通过创建一个名为 tf 的数据库进行测试,连接到它,然后创建pl/python3u过程语言(u 是故意的;它是 PostgreSQL 命名约定的一部分,表明这是一种不受信任的语言,即一种不受沙盒保护的语言)。然后,我们创建一个简单的函数来导入 Tensorflow 库并返回版本号。最后,我们使用SELECT调用该函数,它返回与我们之前看到的pip3安装的Tensorflow版本号相同的版本号。
所以,看起来一切都已准备就绪,可以开始了!
pl/python3 基础知识
当我们测试 Tensorflow 安装时,我们创建了一个简单的 pl/python3 函数,它只返回一个值。在实践中,我们可能需要能够将值传递给函数、引发错误、执行 SQL 查询以及读写文件。
传递和返回值
为了将值传递给函数,我们在创建函数时声明它们,并且可以立即从我们的 Python 代码中访问变量。例如:
tf=# CREATE FUNCTION py_add(a integer, b integer)tf=# RETURNS integertf=# AS $$tf=# return a+btf=# $$ LANGUAGE plpython3u;tf=# SELECT py_add(4, 5);py_add--------9(1 row)tf=#
SQL 代码围绕着 Python 代码,可以在 $$ 标记之间看到。
请注意,您不能重新定义从函数内部传递给函数的参数值,除非您在函数体中将它们声明为全局变量。
传递给 pl/python3 函数的数组在 Python 中被转换为列表(或嵌套列表),如果返回,将以另一种方式转换回来。可以通过返回列表元组或类似结构、迭代器或生成器来返回行集。
显示消息
由于 print() 在 pl/python3 中不起作用,我们需要另一种方式来向用户输出消息,使用 PostgreSQL 的日志基础结构(它还处理发送到客户端接口的消息)。我们可以提出通知、错误、警告等。例如:
tf=# CREATE FUNCTION hello_world()tf-# RETURNS voidtf-# AS $$tf$# plpy.notice('Hello world!')tf$# $$ LANGUAGE plpython3u;CREATE FUNCTIONtf=# SELECT hello_world();NOTICE: Hello world!hello_world-------------(1 row)tf=#
请注意,引发错误(或致命)将导致引发 Python 异常,如果未捕获和处理该异常,该异常将传播回 PostgreSQL,从而导致事务中止。
执行 SQL 查询
如果我们要真正结合机器学习、Python 和 PostgreSQL 的强大功能,能够在我们的函数中执行 SQL 查询至关重要。谢天谢地,这很容易。在这个例子中,我们为我们数据库中的所有表选择名称、模式和所有者,将数据加载到 Pandas 数据帧中,然后打印出一个样本(pandas 会为我们很好地格式化):
tf=# CREATE FUNCTION show_tables()tf-# RETURNS voidtf-# AS $$tf$# import pandas as pdtf$#tf$# tables = plpy.execute('SELECT schemaname, tablename, tableowner FROM pg_tables;')tf$#tf$# columns = list(rows[0].keys())tf$# df = pd.DataFrame.from_records(tables, columns = columns)tf$#tf$# plpy.notice('Tables: \n{}'.format(df))tf$# $$ LANGUAGE plpython3u;tf=# SELECT show_tables();NOTICE: Tables:schemaname tablename tableowner0 pg_catalog pg_statistic postgres1 pg_catalog pg_type postgres2 pg_catalog pg_foreign_table postgres3 pg_catalog pg_authid postgres4 pg_catalog pg_statistic_ext_data postgres.. ... ... ...61 pg_catalog pg_subscription_rel postgres62 information_schema sql_implementation_info postgres63 information_schema sql_parts postgres64 information_schema sql_sizing postgres65 information_schema sql_features postgres[66 rows x 3 columns]show_tables-------------(1 row)tf=#
读写文件
在使用 Tensorflow 时,我们需要在磁盘上读写文件。
当一个函数在 PostgreSQL 中执行时,我们必须记住,就操作系统而言,它是由运行 PostgreSQL 的用户帐户执行的,而不管哪个用户实际调用了该函数,通常称为服务帐户。这意味着从 pl/python3 函数写入的任何文件都将由服务帐户(通常是 postgres)拥有,并且将在非 Windows 平台上以非常严格的权限创建,通常只允许服务帐户读取或写入文件. 文件必须写入服务帐户有权写入的目录,当然,任何要读取的文件也必须可由服务帐户访问。在 Windows 上,PostgreSQL 不会尝试操作文件系统 ACL 本身,
从 pl/python3 读取/写入文件时使用绝对路径也是一个好主意。postgres 进程的工作目录将是数据目录,在那里写入文件通常不是一个好主意。相反,在别处创建一个合适的目录并通过绝对路径使用它,以避免相对路径的任何复杂性或错误。
结论
在这篇文章中,我们介绍了使用 pl/python3 设置 PostgreSQL 安装的基础知识,以便我们可以在我们的数据库中使用 Tensorflow(和其他 Python 库)。我们还介绍了 pl/python3 的一些基础知识,这将有助于我们稍后开始将机器学习技术集成到我们的 PostgreSQL 数据库中。
当我最初开始写这篇博文时,它的目的是成为一篇涵盖 PostgreSQL 设置和使用 Tensorflow 的文章。很快就很明显,如果我要做的不仅仅是浏览细节,这将导致比预期更长的帖子,这真的不是我想要的。
所以现在我们已经完成了所有设置并且熟悉了 pl/python3 的基础知识,请注意第二部分,我将在其中介绍一些我们可以分析数据并对其进行预处理以训练模型的方法。
同时,看看pl/python3 必须提供的其他一些有用的功能。
https://www.postgresql.org/docs/current/plpython.html




