Python中的有效数据验证

时间:2014-01-27 03:51:53

标签: python database validation input

我使用Python和sqlite3来维护数据库,在我插入任何内容之前,我需要对数据执行验证检查,以便我知道,即使非常宽容的数据库会接受垃圾输入,所以实际发生的是不是垃圾输入。

要实现这一点,表示数据库记录且其字段与列匹配的类将在同一模块中具有类似这样的方法:

def validate_path(path):
   if path == None:
      return False
   if len(path) < 5:
      return False
   if not re.search("^/[a-zA-Z0-9_/]+/$", path):
      return False
   else:
      return True

def validate_server(server):
   if server == None:
      return False
   if len(server) < 3:
      return False
   if not re.search("^[a-z][a-zA-Z0-9]+$", server):
      return False
   else:
      return True

def validate_name(name):
   if name == None:
      return False
   if len(name) < 3:
      return False
   if not re.search("^[a-z][a-z_]+$", name):
      return False
   else:
      return True

在完成目标的过程中,这很容易理解,但我觉得如果陈述/非常“初学者”解决问题,效率很低/太多。

然后在我的班上,我将有一个方法,如:

   def validate(self):
      if validate_name(self.name) == False or \
         validate_server(self.home_file_server) == False or \
         validate_path(self.home_path) == False or \
         validate_server(self.web_file_server) == False or \
         validate_path(self.web_path) == False:
         return False
      else:
         return True

这样在运行我的INSERT命令之前,我运行:

if dbrecord.validate() == False:
   # do not insert
else:
   # insert

各个验证方法保存在模块级别(不在类中),因为在评估客户端脚本中的用户输入时使用相同的方法。例如:

while True:
  home_path = raw_input("Home directory path: ")

  if AccountTypeManager.validate_path(home_path) == False:
     print "Invalid home directory path"
     logger.debug("User input home directory path {0} deemed invalid".format(home_path))
     continue

  logger.debug("User input home directory path {0} accepted as valid input.".format(home_path))
  break

我在这两种方法中都进行了验证(除了客户端脚本输入之外),因为该方法可能会在其他地方重复使用,或者以其他方式重复使用,不需要客户端输入,也不考虑数据的来源,在进入之前必须进行检查。

我主要关心的是可维护性和可读性。我想避免使用外部模块,因为很可能我的继任者没有Python经验并且像我一样从头开始。我希望以“Pythonic”的方式完成上述操作,这种方式在非Python背景下也很容易接近。

我也听说在Python中,最好使用Exceptions进行验证,而不是使用True / False值。这是真的吗?

1 个答案:

答案 0 :(得分:2)

我在您的代码中看到了一些冗余。我认为可以提供帮助的是:

存储dict中匹配的模式。 (沿着这条路线,您还必须存储长度)

将验证功能合并为一个。

将if语句合并到pythonic all语句中。

考虑使用和在validate函数中找到一个错误

E.g。

pattern_dict = {'server' : '^[a-z][a-zA-Z0-9]+$',...}

def aux_validate(my_input,input_type):
    return all([my_input is not None, re.search(pattern_dict[input_type],my_input),...])


def validate(self):
    validator = True
    for my_input,input_type in self.inputs:
        validator = validator and aux_validate(my_input,input_type)
    return validator

如果你想获得一点点发烧友,你可以考虑使用一个列表理解与验证并返回所有,即

return all([aux_validate(my_input,input_type) for my_input,input_type in self.inputs])

最后,这可能被视为自以为是,您可以更好地检查http://codereview.stackexchange.com