在插入数据联合模式之前验证参数字典
validating parameter dictionaries before insertion in datajoint schema
我们想在人们可以插入到架构之前强制执行参数检查,如下所示,但下面的代码不起作用。
有没有办法实现预插入参数检查?
@schema
class AutomaticCurationParameters(dj.Manual):
definition = """
auto_curation_params_name: varchar(200) # name of this parameter set
---
merge_params: blob # dictionary of params to merge units
label_params: blob # dictionary params to label units
"""
def insert1(key, **kwargs):
# validate the labels and then insert
#TODO: add validation for merge_params
for metric in key['label_params']:
if metric not in _metric_name_to_func:
raise Exception(f'{metric} not in list of available metrics')
comparison_list = key['label_params'][metric]
if comparison_list[0] not in _comparison_to_function:
raise Exception(f'{metric}: {comparison_list[0]} not in list of available comparisons')
if type(comparison_list[1]) != int and type(comparison_list) != float:
raise Exception(f'{metric}: {comparison_list[1]} not a number')
for label in comparison_list[2]:
if label not in valid_labels:
raise Exception(f'{metric}: {comparison_list[2]} not a valid label: {valid_labels}')
super().insert1(key, **kwargs)
这是一个很好的问题,我们已经多次提出这个问题。
问题很可能是您缺少 class' self
引用,或者您缺少 key
作为关键字参数传入的情况(我们实际上期望它是 row
。
我将演示一个简单示例,希望它可以说明如何注入您的验证代码,您可以调整验证代码以按照您上面的意图执行。
假设,我们想跟踪 dj.Manual
table 中的文件路径,但我想验证是否只插入了具有特定扩展名的文件路径。
正如您已经发现的那样,我们可以像这样通过重载来实现这一点:
import datajoint as dj
schema = dj.Schema('rguzman_insert_validation')
@schema
class FilePath(dj.Manual):
definition = '''
file_id: int
---
file_path: varchar(100)
'''
def insert1(self, *args, **kwargs): # Notice that we need a reference to the class
key = kwargs['row'] if 'row' in kwargs else args[0] # Handles as arg or kwarg
if '.md' not in key['file_path']:
raise Exception('Sorry, we only support Markdown files...')
super().insert1(*args, **kwargs)
P.S。尽管此示例旨在说明概念,但如果您使用 MySQL8,实际上还有更好的方法来执行上述操作。 MySQL 提供了一个 CHECK
实用程序,它允许 DataJoint 遵守的简单验证。如果满足这些条件,您可以将其简化为:
import datajoint as dj
schema = dj.Schema('rguzman_insert_validation')
@schema
class FilePath(dj.Manual):
definition = '''
file_id: int
---
file_path: varchar(100) CHECK(REGEXP_LIKE(file_path, '^.*\.md$', 'c'))
'''
我们想在人们可以插入到架构之前强制执行参数检查,如下所示,但下面的代码不起作用。
有没有办法实现预插入参数检查?
@schema
class AutomaticCurationParameters(dj.Manual):
definition = """
auto_curation_params_name: varchar(200) # name of this parameter set
---
merge_params: blob # dictionary of params to merge units
label_params: blob # dictionary params to label units
"""
def insert1(key, **kwargs):
# validate the labels and then insert
#TODO: add validation for merge_params
for metric in key['label_params']:
if metric not in _metric_name_to_func:
raise Exception(f'{metric} not in list of available metrics')
comparison_list = key['label_params'][metric]
if comparison_list[0] not in _comparison_to_function:
raise Exception(f'{metric}: {comparison_list[0]} not in list of available comparisons')
if type(comparison_list[1]) != int and type(comparison_list) != float:
raise Exception(f'{metric}: {comparison_list[1]} not a number')
for label in comparison_list[2]:
if label not in valid_labels:
raise Exception(f'{metric}: {comparison_list[2]} not a valid label: {valid_labels}')
super().insert1(key, **kwargs)
这是一个很好的问题,我们已经多次提出这个问题。
问题很可能是您缺少 class' self
引用,或者您缺少 key
作为关键字参数传入的情况(我们实际上期望它是 row
。
我将演示一个简单示例,希望它可以说明如何注入您的验证代码,您可以调整验证代码以按照您上面的意图执行。
假设,我们想跟踪 dj.Manual
table 中的文件路径,但我想验证是否只插入了具有特定扩展名的文件路径。
正如您已经发现的那样,我们可以像这样通过重载来实现这一点:
import datajoint as dj
schema = dj.Schema('rguzman_insert_validation')
@schema
class FilePath(dj.Manual):
definition = '''
file_id: int
---
file_path: varchar(100)
'''
def insert1(self, *args, **kwargs): # Notice that we need a reference to the class
key = kwargs['row'] if 'row' in kwargs else args[0] # Handles as arg or kwarg
if '.md' not in key['file_path']:
raise Exception('Sorry, we only support Markdown files...')
super().insert1(*args, **kwargs)
P.S。尽管此示例旨在说明概念,但如果您使用 MySQL8,实际上还有更好的方法来执行上述操作。 MySQL 提供了一个 CHECK
实用程序,它允许 DataJoint 遵守的简单验证。如果满足这些条件,您可以将其简化为:
import datajoint as dj
schema = dj.Schema('rguzman_insert_validation')
@schema
class FilePath(dj.Manual):
definition = '''
file_id: int
---
file_path: varchar(100) CHECK(REGEXP_LIKE(file_path, '^.*\.md$', 'c'))
'''