TorQ: .loader.loadallfiles 和引用完整性导致“转换错误”

TorQ: .loader.loadallfiles and referential integrity leads to `cast error

我有一个tablevolatilitysurface和一个细节tablevolatilitysurface_smile作为细节的一部分table我定义了一个外键给主table即

volatilitysurface::([date:`datetime$(); ccypair:`symbol$()] atm_convention:`symbol$(); ...);
volatilitysurface_smile::([...] volatilitysurface:`volatilitysurface$(); ...);

当我尝试使用 AquaQ's TorQ .loader.loadallfiles 加载详细信息时 table volatilitysurface_smile 我需要作为 "dataprocessfunc" 函数的一部分来动态构建外键字段,即

rawdatadir:hsym `$("" sv (getenv[`KDBRAWDATA]; "volatilitysurface_smile"));
.loader.loadallfiles[`headers`types`separator`tablename`dbdir`partitioncol`partitiontype`dataprocessfunc!(`x`ccypair...;"ZS...";enlist ",";`volatilitysurface_smile;target;`date;`month;{[p;t] select date,ccypair,volatilitysurface,... from update date:x,volatilitysurface:`volatilitysurface$(x,'ccypair) from t}); rawdatadir];

注意部分:

update date:x,volatilitysurface:`volatilitysurface$(x,'ccypair) from t

转换错误指向 volatilitysurface 键的构造。但是,这在 .loader.loadallfiles 之外有效,并且 table 是全局 :: 并且在调用 .loader.loadallfiles 函数之前完全定义。

有什么想法可以处理这个用例吗?如果 detail table 外键没有初始化那么插入会失败。

该错误可能是由于更新中的范围界定所致。由于您是 运行 .loader 命名空间中的 cast/update,因此表名需要具有完整范围 (`..volatilitysurface).

例如。 update date:x,volatilitysurface:`..volatilitysurface$(x,'ccypair) from t

此致,

斯科特

您确定所有可能的 x 和 ccypair 组合都在 volatilitysurface table 中吗? 'cast 错误似乎表明情况并非如此,例如

q)t:([a:1 2 3;b:`a`b`c] c:"ghi")
q)update t:`t$(a,'b) from ([] a:2 3 1;b:`b`c`a)
a b t
-----
2 b 1
3 c 2
1 a 0
q)update t:`t$(a,'b) from ([] a:2 3 1 5;b:`b`c`a`d)
'cast
  [0]  update t:`t$(a,'b) from ([] a:2 3 1 5;b:`b`c`a`d)
              ^

请注意,在第二种情况下,我有 (5;`d) 的 a-b 对,它不存在于 table t 中,所以我得到 'cast 错误

您可以确定是否缺少密钥,以及它们是什么,如下所示:

q)all (exec (a,'b) from ([] a:2 3 1;b:`b`c`a)) in key t                //check for presence, all present
1b
q)all (exec (a,'b) from ([] a:2 3 1 5;b:`b`c`a`d)) in key t            //check for presence, not all present
0b
q)k where not (k:exec (a,'b) from ([] a:2 3 1 5;b:`b`c`a`d)) in key t  //check which keys AREN'T present
5 `d

如果是这种情况,我想你有两种选择:

  • 确保 volatilitysurface table 被正确加载 - 假设你的文件中有完整的数据覆盖,大概每个可能的键都应该出现在这个 table
  • 如果 volatilitysurface 中可能不存在键 table,您可以在创建外键之前向其中添加虚拟记录(如果稍后出现实际记录,则可以将其替换)

第二个选项可能会像这样工作:

q.test){if[count k:k where not (k:exec (a,'b) from x) in key `..t;@[`..t;;:;value[`..t](0N;`)]'[k]];update t:`t$(a,'b) from x}([] a:2 3 1;b:`b`c`a)
a b t
-----
2 b 1
3 c 2
1 a 0
q.test){if[count k:k where not (k:exec (a,'b) from x) in key `..t;@[`..t;;:;value[`..t](0N;`)]'[k]];update t:`t$(a,'b) from x}([] a:2 3 1 5 6;b:`b`c`a`d`e)
a b t
-----
2 b 1
3 c 2
1 a 0
5 d 3
6 e 4
q.test)value `..t //check table t, new dummy records added by previous call
a b| c
---| -
1 a| g
2 b| h
3 c| i
5 d|
6 e|

我已经在命名空间内完成了这些测试,因为这就是数据处理函数在 TorQ 中 运行 的方式(即在某些地方你需要使用 `..t 来访问 t在根命名空间中。)此函数的类似版本(具有比上面的单行代码更好的格式)类似于:

{
  if[count k:k where not (k:exec (x,'ccypair from volatilitysurface_smile) in key `..volatilitysurface;  //check for missing keys
  @[`..volatilitysurface;;:;value[`..volatilitysurface](0Nz;`)]'[k]];  //index into null key of table to get dummy record and upsert to global volatilitysurface table
  update volatilitysurface:`volatilitysurface$(x,'ccypair) from x  //create foreign key
 }