插入时自动在增量表中增加ID

时间:2019-12-03 11:38:31

标签: apache-spark pyspark apache-spark-sql delta-lake

我在使用带有dels table的pysparkSQL合并csv文件时遇到问题。我设法创建upsert函数,如果匹配则更新,如果不匹配则插入。

我想将列ID添加到最终的增量表中,并在每次插入数据时对其进行递增。此列标识增量表中的每一行。有什么办法可以实现这一点?

def Merge(dict1, dict2):
    res = {**dict1, **dict2}
    return res

def create_default_values_dict(correspondance_df,marketplace):
    dict_output = {}
    for field in get_nan_keys_values(get_mapping_dict(correspondance_df, marketplace)):
        dict_output[field] = 'null'
        # We want to increment the id row each time we perform an insertion (TODO TODO TODO)
#         if field == 'id':
#             dict_output['id'] = col('id')+1
#         else:    
    return dict_output


def create_matched_update_dict(mapping, products_table, updates_table):
    output = {}
    for k,v in mapping.items():
        if k == 'source_name':
            output['products.source_name'] = lit(v)
        else:
            output[products_table + '.' + k] = F.when(col(updates_table + '.' + v).isNull(), col(products_table + '.' + k)).when(col(updates_table + '.' + v).isNotNull(), col(updates_table + '.' + v))     
    return output    

insert_dict = create_not_matched_insert_dict(mapping, 'products', 'updates')
default_dict = create_default_values_dict(correspondance_df_products, 'Cdiscount')

insert_values = Merge(insert_dict, default_dict)
update_values = create_matched_update_dict(mapping, 'products', 'updates')

delta_table_products.alias('products').merge(
    updates_df_table.limit(20).alias('updates'),
    "products.barcode_ean == updates.ean") \
    .whenMatchedUpdate(set = update_values) \
    .whenNotMatchedInsert(values = insert_values)\
    .execute()

我试图递增函数id中的列create_default_values_dict,但似乎无法正常工作,它不能自动递增1。是否有另一种方法可以解决此问题?在此先感谢:)

1 个答案:

答案 0 :(得分:0)

Delta不支持自动增量列类型。

通常,Spark不使用自动递增的ID,而倾向于单调递增的ID。参见functions.monotonically_increasing_id()

如果要实现自动增量行为,则必须使用多个Delta操作,例如,查询最大值,然后将其添加到通过窗口函数计算的row_number()列中,然后进行写入。这有问题,原因有两个:

  1. 除非引入外部锁定机制或其他方法以确保在找到最大值与写入之间不发生表更新,否则最终将导致无效数据。

  2. 使用row_number()会将并行度降低为1,强制所有数据通过单个内核,这对于大数据将非常慢。

最重要的是,您真的不想在Spark中使用自动增量列。

希望这会有所帮助。