将表插入到内存中现有的展开表导致错误:`type (Q/KDB+)
Posted
技术标签:
【中文标题】将表插入到内存中现有的展开表导致错误:`type (Q/KDB+)【英文标题】:Upsert a table to existing splayed table in memory leading to error: `type (Q/KDB+) 【发布时间】:2022-01-23 18:11:49 【问题描述】:我正在使用新的 Q 语言和 KDB+ 数据库。我无法将另一个表插入到内存中现有的张开表中。
我有一个名为temp
的表格,然后将其保存为`:temp
中的张开表格
col1 col2 col3
--------------
a 0 1
b 1.5 2.5
c 1.1 2.2
d 0.99 0.98
张开表的目录结构:
temp
| .d
| col1
| col2
| col3
| sym
假设我有另一张桌子new
new: ([] col1:`e`f`g; col2:1.0 1.1 1.1; col3: 2.25 2.20 2.70)
我的问题是:我们如何将new
插入`:temp
?
我已经阅读了https://code.kx.com/q/ref/upsert/,但是给出的示例只更新了一条记录(而不是整个表)。我试过`:temp upsert (`sym?new)
导致type
错误。
编辑(我运行的所有命令)
q)temp: ([] col1:`a`b`c`d; col2:0.0 1.5 1.1 0.99; col3: 1.0 2.5 2.2 0.98)
q)`:temp/ set .Q.en[`:.;temp]
`:temp/
q)new: ([] col1:`e`f`g; col2:1.0 1.1 1.1; col3: 2.25 2.20 2.70)
q)`:temp upsert new
'type
[0] `:temp upsert new
^
【问题讨论】:
【参考方案1】:如果您已经将temp
保存为张开的表格,您可以使用以下命令将new
插入到其中:
q) new:([]col1:`e`f`g;col2:1.0 1.1 1.1;col3:2.25 2.20 2.70)
q) `:temp upsert new
`:temp
q) get`:temp
col1 col2 col3
--------------
a 0 1
b 1.5 2.5
c 1.1 2.2
d 0.99 0.98
e 1 2.25
f 1.1 2.2
g 1.1 2.7
然后您就可以看到所需的结果。如果您离开 q 会话并将其加载到新会话中,您将看到它已被保存。
【讨论】:
嗯,我仍然收到`:type
错误。当我将temp
保存为张开的表格时,我怀疑代码不正确。这是保存张开的桌子的正确方法吗? temp:.Q.en[`:temp;temp]
后跟`:temp/ set temp
【参考方案2】:
您需要使用enum extend“手动”枚举任何符号类型列
q)`:temp/ set([]col1:`:sym?`a`b;col2:1 2f;col3:10 20f);
q)`:temp upsert([]col1:`:sym?`e`f`g;col2:1.0 1.1 1.1;col3:2.25 2.20 2.70);
q)get`:sym
`a`b`e`f`g
q)get`:temp
col1 col2 col3
--------------
a 1 10
b 2 20
e 1 2.25
f 1.1 2.2
g 1.1 2.7
或使用.Q.en等辅助函数之一
q)`:temp/ set .Q.en[`:.;([]col1:`A`B;col2:1 2f;col3:10 20f)];
q)`:temp upsert .Q.en[`:.;([]col1:`e`f`g;col2:1.0 1.1 1.1;col3:2.25 2.20 2.70)];
q)get`:sym
`A`B`e`f`g
q)get`:temp
col1 col2 col3
--------------
A 1 10
B 2 20
e 1 2.25
f 1.1 2.2
g 1.1 2.7
在更新插入持久文件时还有其他需要注意的事项,例如
任何应用了属性的文件都将通过 upsert 操作删除这些属性(排序除外,如果列表保持升序,则会保留该属性) 如果任何带有属性的文件被压缩,除非您采取其他措施以确保它们不会被压缩,否则它们将在未压缩的情况下被重写q)(`:groupedVector;17;2;6)set `g#1 2 3;
q)-21!`:groupedVector
compressedLength | 113
uncompressedLength| 240
algorithm | 2i
logicalBlockSize | 17i
zipLevel | 6i
q)attr get`:groupedVector
`g
q)
q)`:groupedVector upsert 4 5;
q)get `:groupedVector
1 2 3 4 5
q)-21!`:groupedVector // compression lost
q)attr get`:groupedVector // attribute lost
`
由开发人员确保磁盘上的列文件与要附加的数据之间的兼容性 - 否则您可能会以不同长度的列文件结束,例如
q)`:temp/ set([]char:"ab";long:1 2);
q)`:temp upsert ("c";3);
q)`:temp upsert ("d";4i);
'type
[0] `:temp upsert ("d";4i);
^
q)get`:temp/char
"abcd"
q)get`:temp/long
1 2 3
【讨论】:
有没有办法在不“手动输入”表定义的情况下进行更新插入?假设我有一个 100 行的张开表,我想更新一百万条记录,手动输入类似([]col1:`:sym?`e`f`g;col2:1.0 1.1 1.1;col3:2.25 2.20 2.70)
的内容是不可能的,对吧?
我期待像`:temp upsert (colnames ! entries)
这样的东西,在上面的例子中colnames
是`col1`col2`col3
。我希望你明白我的意思
@Meinung 命令将与表名相同,例如`:temp/ set .Q.en[`:.;temp]
,我也注意到您保存枚举的方式意味着您将 sym 文件保存在与列相同的位置,确保它与表目录相同,即使用上面的示例,不要使用`:temp/ set .Q.en[`:temp;temp]
@CameronMcKee 谢谢你的建议。但我仍然无法将新记录更新到`:temp
。我已经尝试了@Leah Carragher 建议的`:temp/ upsert new
,但我仍然收到`type
错误。如果我问的事情太琐碎,我深表歉意
哦,我终于可以在不通过`:temp upsert .Q.en[`:.] new
得到`type
错误的情况下进行更新插入了!!非常感谢大家的帮助以上是关于将表插入到内存中现有的展开表导致错误:`type (Q/KDB+)的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery:将表插入到具有分片表的现有 Google 分析中
将表插入到我使用 sqlite 在 python 中创建的数据库中时出错
新手试图从 excel 将数据插入 SQL Server 2008
关于字段超长导致的插入错误的提示信息(value too long for type character varying)