我有一个 sql 查询字符串,如下所示:
intro text,
id int,
description varchar(50)
我正在尝试创建一个类型字符串,目的是找到与 sql 模式中定义的类型不匹配的文本片段。我从 sql 文本中提取类型的方式如下:
types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema]
types = [re.sub('varchar',types.StringType,x) for x in types]
types = [re.sub('text',types.StringType,x) for x in types]
types = [re.sub('bigint',types.IntType,x) for x in types]
types = [re.sub('decimal',types.IntType,x) for x in types]
然而口译员提示说
types = [re.sub('varchar',types.StringTypes,x) for x in types]
AttributeError: 'list' object has no attribute 'StringTypes'
一个SSCCE
使用以下架构文件
intro text,
id int,
description varchar(50)
和代码(注意,按照下面 oscar 的建议修复,但现在有其他错误)
import csv
import sys
import re
import types
sch = open(sys.argv[1], "rb")
#---------------------------------
# read schema
#---------------------------------
with sch as f:
schema = f.read().splitlines()
#---------------------------------
# extract schema types
#---------------------------------
foundtypes = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema]
foundtypes = [re.sub('varchar',str,x) for x in foundtypes]
foundtypes = [re.sub('text',str,x) for x in foundtypes]
foundtypes = [re.sub('int',int,x) for x in foundtypes]
foundtypes = [re.sub('bigint',int,x) for x in foundtypes]
foundtypes = [re.sub('decimal',int,x) for x in foundtypes]
print foundtypes
我正在使用 Python 2.7.5
谢谢
请您参考如下方法:
您将绑定(bind)(参见:variable shadowing)改写为 types module , 在这一行中:
types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema]
之后,types不再指向模块,而是指向一个列表。只需在所有作业中使用另一个名称即可:
my_types = [re.sub('[^a-zA-Z]','',x.split()[1]) for x in schema]
my_types = [re.sub('varchar',types.StringType,x) for x in my_types]
my_types = [re.sub('text',types.StringType,x) for x in my_types]
my_types = [re.sub('bigint',types.IntType,x) for x in my_types]
my_types = [re.sub('decimal',types.IntType,x) for x in my_types]
更新
我认为您过度设计了解决方案,除了第一行,这不适合使用正则表达式。一个简单的 if-elif-else 就可以正常工作:
def transform(typestr):
if typestr in ('varchar', 'text'):
return types.StringType
elif typestr in ('int', 'bigint', 'decimal'):
return types.IntType
else:
return None
my_types = [re.sub(r'[^a-zA-Z]', '', x.split()[1]) for x in schema]
[transform(x) for x in my_types]
=> [<type 'str'>, <type 'int'>, <type 'str'>]
