使用标量 Python 为亚马逊 Redshift 查询结果设置特定语言的排序 UDF - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用标量 Python 为亚马逊 Redshift 查询结果设置特定语言的排序 UDF

由 Ethan Stark 创作 () AWS

摘要

此模式提供了使用标量 PythonUDF(用户定义的函数)为 Amazon Redshift 查询结果设置不区分大小写的语言排序的步骤和示例代码。必须使用标量 Python,UDF因为 Amazon Redshift 会根据UTF二进制 -8 排序返回结果,并且不支持特定语言的排序。Python UDF 是基于 Python 2.7 程序并在数据仓库中运行的非SQL处理代码。您可以在单个查询中使用SQL语句运行 Python UDF 代码。有关更多信息,请参阅亚马逊 Redshift AWS 大数据UDFs中的 Python 简介博客文章。

此模式中的示例数据基于土耳其字母表,用于演示目的。这种模式UDF中的标量 Python 旨在使 Amazon Redshift 的默认查询结果符合土耳其语中字符的语言顺序。有关更多信息,请参阅此模式的其他信息部分中的土耳其语示例。你可以用这种模式修改其他语言UDF的标量 Python。

先决条件和限制

先决条件

限制

此模式中的查询使用的语言排序不区分大小写。

架构

技术堆栈

  • Amazon Redshift

  • Python UDF

工具

AWS 服务

  • Amazon Redshift 是一项托管的 PB 级云端数据仓库服务。AWSAmazon Redshift 与数据湖集成,让您可以使用数据获得对您的业务和客户的新见解。

其他工具

操作说明

任务描述所需技能

为您的示例数据创建一个表。

要在 Amazon Redshift 中创建表并将您的示例数据插入表中,请使用以下语句:SQL

CREATE TABLE my_table (first_name varchar(30)); INSERT INTO my_table (first_name) VALUES ('ali'), ('Ali'), ('ırmak'), ('IRMAK'), ('irem'), ('İREM'), ('oğuz'), ('OĞUZ'), ('ömer'), ('ÖMER'), ('sedat'), ('SEDAT'), ('şule'),
注意

样本数据中的名字包括土耳其语字母表中的特殊字符。有关此示例中土耳其语注意事项的更多信息,请参阅此模式的其他信息部分中的土耳其语示例

数据工程师

检查样本数据默认排序。

若要在 Amazon Redshift 中查看示例数据的默认排序,请运行以下查询:

SELECT first_name FROM my_table ORDER BY first_name;

该查询返回您之前创建表中的名字列表:

first_name --------------- Ali IRMAK OĞUZ SEDAT ali irem oğuz sedat ÖMER ömer İREM ırmak ŞULE şule

查询结果的顺序不正确,因为默认的二进制 UTF -8 排序不符合土耳其语特殊字符的语言顺序。

数据工程师

创建一个标量 Python UDF。

要创建标量 PythonUDF,请使用以下SQL代码: 

CREATE OR REPLACE FUNCTION collate_sort (value varchar) RETURNS varchar IMMUTABLE AS $$ def sort_str(val): import string dictionary = { 'I': 'ı', 'ı': 'h~', 'İ': 'i', 'Ş': 's~', 'ş': 's~', 'Ğ': 'g~', 'ğ': 'g~', 'Ü': 'u~', 'ü': 'u~', 'Ö': 'o~', 'ö': 'o~', 'Ç': 'c~', 'ç': 'c~' } for key, value in dictionary.items(): val = val.replace(key, value) return val.lower() return sort_str(value) $$ LANGUAGE plpythonu;
数据工程师

查询示例数据。

要使用 Python 查询示例数据UDF,请运行以下SQL查询:

SELECT first_name FROM my_table ORDER BY collate_order(first_name);

现在,查询以土耳其语顺序返回示例数据:

first_name --------------- ali Ali ırmak IRMAK irem İREM oğuz OĞUZ ömer Ömer sedat SEDAT şule ŞULE
数据工程师

相关资源

其他信息

土耳其语示例

Amazon Redshift 根据二进制 UTF -8 排序顺序返回查询结果,而不是特定语言的排序顺序。这意味着,如果您查询包含土耳其语字符的 Amazon Redshift 表,则查询结果不会根据土耳其语的语言顺序进行排序。土耳其语包含六个不出现在拉丁字母表中的特殊字符 (ç、ı、ğ、 ö、ş, 以及 ü)。如下表所示,这些特殊字符根据二进制 UTF -8 排序放在排序结果集的末尾。

二进制 UTF -8 排序

土耳其语语言排序

a

a

b

b

c

c

d

ç (*)

e

d

f

e

g

f

h

g

i

ğ (*)

j

h

k

ı (*)

l

i

m

j

n

k

o

l

p

m

r

n

s

o

t

ö (*)

u

p

v

r

y

s

z

ş (*)

ç (*)

t

ğ (*)

u

ı (*)

ü (*)

ö (*)

v

ş (*)

y

ü (*)

z

注意

星号 (*) 表示土耳其语中的特殊字符。

如上表所示,特殊字符 q 在土耳其语排序中介于 cd 之间,但按二进制 UTF -8 顺序出现在 z 之后。此模式UDF中的标量 Python 使用以下字符替换字典将土耳其语特殊字符替换为相应的拉丁语等效字符。

土耳其语特殊字符

拉丁语等效字符

ç

c~

ı

h~

ğ

g~

ö

o~

ş

s~

ü

u~

注意

在替换相应土耳其语特殊字符的拉丁字符的末尾附加波浪号 (~) 字符。

修改标量 Python 函数 UDF

要修改此模式中的标量 Python UDF 函数,使该函数接受定位参数并支持多事务字典,请使用以下SQL代码:

CREATE OR REPLACE FUNCTION collate_sort (value varchar, locale varchar) RETURNS varchar IMMUTABLE AS $$ def sort_str(val): import string # Turkish Dictionary if locale == 'tr-TR': dictionary = { 'I': 'ı', 'ı': 'h~', 'İ': 'i', 'Ş': 's~', 'ş': 's~', 'Ğ': 'g~', 'ğ': 'g~', 'Ü': 'u~', 'ü': 'u~', 'Ö': 'o~', 'ö': 'o~', 'Ç': 'c~', 'ç': 'c~' } # German Dictionary if locale == 'de-DE': dictionary = { .... .... } for key, value in dictionary.items(): val = val.replace(key, value) return val.lower() return sort_str(value) $$ LANGUAGE plpythonu;

以下示例代码显示如何查询修改后的 PythonUDF:

SELECT first_name FROM my_table ORDER BY collate_order(first_name, 'tr-TR');