Redshift Copy和自动增量不起作用

时间:2015-01-22 15:08:25

标签: amazon-redshift

我正在使用redshift中的COPY命令从S3复制json数据。 表定义如下:

CREATE TABLE my_raw
(
id BIGINT IDENTITY(1,1),
...
...
) diststyle even;

我正在使用的复制命令如下:

COPY my_raw FROM 's3://dev-usage/my/2015-01-22/my-usage-1421928858909-15499f6cc977435b96e610298919db26' credentials 'aws_access_key_id=XXXX;aws_secret_access_key=XXX' json 's3://bemole-usage/schemas/json_schema' ; 

我希望插入的任何新ID都将始终为>从my_raw中选择max(id)。事实上,情况显然并非如此。

如果我发出两次上面的复制命令,第一次id从1开始到N虽然该文件正在创建114条记录(当它有多个分片时,这是红移的已知问题)。第二次id也介于1和N之间,但它使用了第一个副本中未使用的空闲数字。

请参阅下面的演示:

usagedb=# COPY my_raw FROM 's3://bemole-usage/my/2015-01-22/my-usage-1421930213881-b8afbe07ab34401592841af5f7ddb31c' credentials 'aws_access_key_id=XXXX;aws_secret_access_key=XXXX' json 's3://bemole-usage/schemas/json_schema' COMPUPDATE OFF;
INFO:  Load into table 'my_raw' completed, 114 record(s) loaded successfully.
COPY
usagedb=# 
usagedb=# select max(id) from my_raw;
 max  
------
 4556
(1 row)

usagedb=# COPY my_raw FROM 's3://bemole-usage/my/2015-01-22/my-usage-1421930213881-b8afbe07ab34401592841af5f7ddb31c' credentials 'aws_access_key_id=XXXX;aws_secret_access_key=XXXX' json 's3://bemole-usage/schemas/my_json_schema' COMPUPDATE OFF;
INFO:  Load into table 'my_raw' completed, 114 record(s) loaded successfully.
COPY
usagedb=# select max(id) from my_raw;
 max  
------
 4556
(1 row)

提前谢谢

2 个答案:

答案 0 :(得分:1)

我发现确保基于插入的顺序ID的唯一解决方案是维护一对表。第一个是阶段表,其中项目由COPY命令插入。舞台表实际上没有ID列。

然后我有另一个表,它是stage表的精确副本,除了它有一个额外的Ids列。然后有一个作业负责使用ROW_NUMBER()函数从舞台填充主表。

实际上,这意味着在执行每个Redshift COPY后执行以下语句:

  insert into master
      (id,result_code,ct_timestamp,...)
  select
      #{startIncrement}+row_number() over(order by ct_timestamp) as id,
      result_code,...
  from stage;

然后保证Ids在主表中是连续的/连续的。

答案 1 :(得分:0)

我无法重现您的问题,但有趣的是如何将身份列与 copy 一起正确设置。这里有一个小小的总结:

请注意,您可以为复制命令指定列(及其顺序)。

<%= form_for :sale, url: sales_path do |f| %>
<p>
  <%= f.label :buyer_details %><br>
  <%= f.text_field :buyer_details %>
</p>
<p>
  <% transaction_collection = ["Cash", "Credit"]%>
  <%= f.label :nature %><br>
  <%= f.select :nature, transaction_collection%>
</p>
<% if @nature == "Credit" %>
  <p>
    <%= f.label :debtor_id %><br>
    <%= f.collection_select :debtor_id, @debtors, :id, :name, prompt: true %>
  </p>
<% end %>
<p>
<%= f.submit %>
</p>
<% end %>

所以如果:

  • EXPLICIT_IDS标志未设置
  • 没有列出如上所示的列
  • 并且您的csv不包含IDENTITY列的数据

然后表格中的标识值将自动设置为我们都想要的单调。

doc

  

如果列列表中包含IDENTITY列,则还必须指定EXPLICIT_IDS;如果省略IDENTITY列,则无法指定EXPLICIT_IDS。如果未指定列列表,则该命令的行为就像指定了完整的有序列列表一样,如果未指定EXPLICIT_IDS,则省略IDENTITY列。