I use Python and sqlite3 to maintain a database, and before I insert anything, I need to perform validation checks on the data so that I know, even if the very forgiving database would accept crap input, that what's going in is actually not crap input.
To accomplish this, a class which represents a database record and whose fields match 1:1 with the columns will have methods like these in the same module:
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
This is easy to understand while accomplishing my goals, but I feel that it's inefficient/too many if statements/a very "beginner" approach to the problem.
Then in my class, I'll have a method like:
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
so that before running my INSERT command, I run:
if dbrecord.validate() == False:
# do not insert
else:
# insert
The individual validation methods are kept at the module level (not in the class), because I use the same methods when evaluating user input in a client script. So for example:
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
I validate in both the method (in addition to the client script input) because the method could potentially be re-used elsewhere or in some other manner which doesn't take client input and without regard for where the data came from, it must be checked before going in.
My primary concern is maintainability and readability. I'd like to avoid using an external module for this, as it is very likely my successor will have no Python experience and start from scratch like I did. I want to accomplish the above in a "Pythonic" way which is also easily approachable from a non-Python background.
I've also heard that in Python, it's better to use Exceptions for validation, as opposed to True/False values. Is this true?