能否修改populate实现使其调用insert代替insert1解决大数据填充超时问题
DataJoint
populate 批量插入优化方案 核心问题原因
你之前自定义的make方法无法被populate触发,是因为DataJoint的make方法强制要求接收key作为入参,populate运行时会自动将待填充的主键值传入该参数,你删掉了这个参数就不符合接口约定,自然无法被调用。
可行实现方案
完全可以在make方法里用批量insert代替循环insert1,性能会提升数十倍,也能避免频繁请求触发的服务器超时。推荐两种实现方式:
方式1:预先收集所有条目为字典列表,最后一次性插入
这是最直观、不易出错的写法:
def make(self, key): # 原有读取数据的逻辑保留 filename = 'data/AJ0{mouse_id}_{session_id}'.format(**key) mat = spio.loadmat(filename, squeeze_me=True, struct_as_record=False) data = mat[list(mat)[-1]] activity_arr = data.deResp n_trials, n_neuron = activity_arr.shape # 新建列表存储所有待插入条目 insert_rows = [] for neuro_id in range(n_neuron): for trial_id in range(n_trials): # 注意不要直接修改传入的key,避免副作用,先copy再赋值 row = key.copy() row['neuro_id'] = neuro_id row['activity'] = activity_arr[trial_id, neuro_id] insert_rows.append(row) # 一次性批量插入 self.insert(insert_rows, skip_duplicates=True)
方式2:用numpy结构化数组批量插入(性能更高)
如果你更习惯用numpy数组操作,也可以直接构造符合表字段结构的数组传入:
def make(self, key): filename = 'data/AJ0{mouse_id}_{session_id}'.format(**key) mat = spio.loadmat(filename, squeeze_me=True, struct_as_record=False) data = mat[list(mat)[-1]] activity_arr = data.deResp n_trials, n_neuron = activity_arr.shape # 构造广播后的数组 trial_ids = np.arange(n_trials) # 先把固定字段扩展成和trial数相同的长度 mouse_id_arr = np.full(n_trials, key['mouse_id']) session_id_arr = np.full(n_trials, key['session_id']) for neuro_id in range(n_neuron): neuro_id_arr = np.full(n_trials, neuro_id) activity_arr_slice = activity_arr[:, neuro_id] # 构造结构化数组,字段名要和你表定义的字段完全对应 insert_arr = np.zeros(n_trials, dtype=[ ('mouse_id', mouse_id_arr.dtype), ('session_id', session_id_arr.dtype), ('trial_id', trial_ids.dtype), ('neuro_id', neuro_id_arr.dtype), ('activity', activity_arr_slice.dtype) ]) insert_arr['mouse_id'] = mouse_id_arr insert_arr['session_id'] = session_id_arr insert_arr['trial_id'] = trial_ids insert_arr['neuro_id'] = neuro_id_arr insert_arr['activity'] = activity_arr_slice self.insert(insert_arr, skip_duplicates=True)
额外注意事项
- 原代码里
self.insert1(Key, skip_duplicates=True)存在笔误,大写的Key应该是小写的变量key,会导致原代码运行报错 - 批量插入时如果数据量特别大(百万行以上),可以拆分批次插入,每批1万-10万行左右,避免单次请求 payload 过大
- 如果你的表有依赖的父表,确保插入的字段包含所有主键,且主键值在父表中存在,避免外键约束报错
内容的提问来源于stack exchange,提问作者Juux
相关产品推荐
相关产品推荐

