在红移中创建Python UDF以替换字符串中的字符

在红移中创建Python UDF以替换字符串中的字符,python,replace,amazon-redshift,user-defined-functions,Python,Replace,Amazon Redshift,User Defined Functions,我的数据库中有一个varchar列。它应该有'43','43000','50000'等值,但有时它有'43000','50','00000'等值,有时它也有垃圾值和其他字符 我要做的是,首先替换值中的所有,“,然后尝试将其转换为int,如果成功,则返回此int值。否则返回null。我正试图为它编写一个Python UDF,但它似乎不起作用。这是: create or replace function isnumeric (aval VARCHAR(20000)) returns int IM

我的数据库中有一个varchar列。它应该有'43','43000','50000'等值,但有时它有'43000','50','00000'等值,有时它也有垃圾值和其他字符

我要做的是,首先替换值中的所有
,“
,然后尝试将其转换为
int
,如果成功,则返回此
int
值。否则返回
null
。我正试图为它编写一个Python UDF,但它似乎不起作用。这是:

create or replace function isnumeric (aval VARCHAR(20000))
  returns int
IMMUTABLE 
as $$
    try:
       aval = aval.replace(',','');
       x = int(aval);
       return x;
    except:
       return (1==2);
       return null;

$$ language plpythonu;

select 

isnumeric(field1) 

from 
table
limit 10000

谁能帮我一下吗?

我认为你不需要自定义项。您可以使用
REGEXP\u INSTR
查找无效值,然后使用
REGEXP\u REPLACE
清除有效字符串中的非数字字符

WITH test_vals AS 
    (          SELECT 'garbage_1' test,   'xx43,000' val 
     UNION ALL SELECT 'decimal'   test,  '43,000.00' val 
     UNION ALL SELECT 'commas'    test,  '50,00,000' val 
     UNION ALL SELECT 'date_val'  test, '2019/03/03' val 
)
SELECT test
       --Any character other than numbers, commas or decimal returns NULL
     , CASE WHEN REGEXP_INSTR(val,'[^0-9,.]') > 0 THEN NULL 
       --Commas are removed, decimal marker is retained
       ELSE REGEXP_REPLACE(val,'[^0-9.]','') END::NUMERIC  AS ouput 
FROM test_vals
;
输出为:

   test    |  ouput
-----------+---------
 garbage_1 |
 decimal   |   43000
 commas    | 5000000
 date_val  |

你能告诉我们程序给出的输出和/或错误吗?如果您能确切地告诉我们它在做什么和不在做什么,我们可以提供更多帮助。@TechPerson我得到的操作无效:布尔类型的输入语法无效:“null”;您的UDF应该返回
int
,而不是
bool
。Python中没有
null
的概念。相反,它使用
None
。如果
返回None
,我不知道Redshift如何处理它,但它可能会将其转换为
NULL
。试试看。(或者,坦率地说,使用下面乔的
CAST
想法,哪个更好。)@JohnRotenstein对于下面乔的想法,我在评论中提到了为什么不能使用它。我尝试将null替换为None,但udf仍然只返回布尔值。它返回布尔值,因为第二行显示“returns bool”。但问题是我只想替换“,”,如果列值包含任何其他字符,我只想把它转换成null,而不是在我的计算中考虑这个值。这是因为如果列包含43000的值,将它们转换为43000是有效的。但是,一些垃圾值包括2019/03/03,但将其转换为20190303是不正确的,因为此列是价格列,有人输入了垃圾日期值。所以我想在计算中忽略它。修改了示例以解决删除无效条目的用例。然而,我建议在这一点上要谨慎。如果数据完全是自由形式的,那么任何深入的分析充其量也可能是不可靠的。祝你好运