使用自定义 Python 库 ua-parser 的 Amazon Redshift UDF

Posted

技术标签:

【中文标题】使用自定义 Python 库 ua-parser 的 Amazon Redshift UDF【英文标题】:Amazon Redshift UDF using custom Python library ua-parser 【发布时间】:2016-08-03 10:16:34 【问题描述】:

我想使用 Python 库在 Redshift 中创建 UDF 函数,特别是 ua-parser 库。

这里描述了在 Redshift 上使用自定义 Python 库的过程http://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_LIBRARY.html

为了获取具有所有依赖项的库,我使用了 aws labs 的 PipLibraryInstaller,它应该将所有依赖库放在 S3 上,与常规 pip 命令相同。

但是我不能让 ua-parser 库使用这个命令。

我使用以下命令创建并上传 lib 到 S3

./installPipModuleAsRedshiftLibrary.sh -m ua-parser -s s3://bucket_location -r region_name

然后我使用以下命令创建库

CREATE OR REPLACE LIBRARY ua_parser
LANGUAGE plpythonu
from 's3://bucket/ua-parser.zip'
WITH CREDENTIALS AS 'aws_access_key_id=AWS_key;aws_secret_access_key=secret_key'
region 'region_name'

然后我创建了函数:

create function f_user_agent_parse (user_agent varchar) returns varchar IMMUTABLE 
as $$
from ua_parser import user_agent_parser as parser

parsed_string = parser.Parse(user_agent)

return type(parsed_string)
$$ 
language plpythonu;

当我尝试执行以下操作时:

select f_user_agent_parse('facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)') as s

我收到以下错误:

错误:XX000:ImportError:没有名为 _regexes 的模块。请查看 svl_udf_log 了解更多信息

看起来 regexes 不在库中。但是,当我从 S3 下载 lib 并查看它时,我看到以下文件:

这里有什么问题?我做错了什么还是图书馆有问题?

【问题讨论】:

【参考方案1】:

实际上问题是我在windows中运行这个命令,但是在windows环境下它不起作用。

很奇怪,虽然 Redshift 的原生客户端是 Aginity,它只在 Windows 上运行,但是我们不能使用 Redshift 提供的 Python 功能

【讨论】:

【参考方案2】:

对我有用:

$ python --version
Python 2.7.10
$ pip --version
pip 7.1.2 from /Library/Python/2.7/site-packages/pip-7.1.2-py2.7.egg (python 2.7)

并从aws-labs执行脚本:

Collecting ua-parser
  Using cached ua_parser-0.7.1-py2.py3-none-any.whl
  Saved /private/var/folders/ty/fw4v8qq54330h_b6tz47c8r40000gn/T/.ua-parser/ua_parser-0.7.1-py2.py3-none-any.whl

但是,我在执行您发布的代码时遇到了另一个问题。 在 Redshift 中执行查询后,我得到:

ERROR:  TypeError: expected string or Unicode object, type found. Please look at svl_udf_log for more information

我把return type(parsed_string)改成了return parsed_string['user_agent']['family']

db=# select f_user_agent_parse('facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)'::varchar(200));
 f_user_agent_parse
--------------------
 FacebookBot
(1 row)

ua-parser.zip内的文件夹结构:

$ unzip ua-parser.zip
Archive:  ua-parser.zip
  inflating: ua_parser/__init__.py
  inflating: ua_parser/_regexes.py
  inflating: ua_parser/user_agent_parser.py
  inflating: ua_parser/user_agent_parser_test.py
  inflating: ua_parser-0.7.1.dist-info/DESCRIPTION.rst
  inflating: ua_parser-0.7.1.dist-info/metadata.json
  inflating: ua_parser-0.7.1.dist-info/top_level.txt
  inflating: ua_parser-0.7.1.dist-info/WHEEL
  inflating: ua_parser-0.7.1.dist-info/METADATA
  inflating: ua_parser-0.7.1.dist-info/RECORD

【讨论】:

我知道代码可能不正确,但我从来没有遇到过那种错误。我知道“_regexes”是不可用的模块。我有 python 2.7.12 和 pip 8.1.2 所以在你从 aws 实验室执行脚本后,直接将库上传到 S3,你是否使用与我上面提供的脚本相同的脚本创建库? 我用 Python 2.7.12 和 pip 8.1.2 为自己创建了一个新环境,但一切仍然运行良好。我也使用了aws-labs 的脚本,它可以毫无问题地上传到 S3。从您的问题来看,听起来您在执行该函数时遇到错误,但现在您写道它在上传到 S3 时已经死机?你能澄清一下吗? Nono,上传到 S3 工作正常。以下是我执行的步骤:1)使用 aws-labs 脚本,创建 ua_parser.zip 并将其上传到 S3 -> 工作正常 2)使用 Aginity 工具在 Redshift 中创建库 -> 成功且没有错误 3)使用 Aginity 客户端在 Redshift 中创建函数-> 成功且没有错误 4) 尝试使用以前创建的函数执行 select 语句,(如问题中所述)-> 我收到错误,即没有名为 _regexes 的模块谢谢 恐怕我无法重现您的错误。我们执行的步骤之间的唯一区别是我们使用的客户端(我通过psql 从命令行发出了所有命令和语句)。我建议删除所有内容,即发出 drop function f_user_agent_parse (user_agent varchar)drop library ua_parser 并重试。如果一切都失败了,我可以将我的 S3 文件发送给您——也许这些文件在某些​​细节上有所不同。 你能给我发一份文件吗?我对floder结构感兴趣,它可能会有所不同。可以私信发给我吗

以上是关于使用自定义 Python 库 ua-parser 的 Amazon Redshift UDF的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Azure Synapse Analytics 将自定义 Python 库导入到 Apache Spark 池中?

如何为机器人框架创建自定义 Python 代码库

如何在 fhirclient-4.0.0 python 库中设置自定义标头?

将现有的 Webdriver 对象传递给 Robot Framework 的自定义 Python 库

Python使用turtle库绘制椭圆图形(自定义旋转角度大小颜色以及填充)

Python使用turtle库绘制椭圆图形(自定义旋转角度大小颜色以及填充)