ADF将Azure表存储中的1到1复制到Azure SQL

时间:2017-04-06 18:40:17

标签: azure azure-sql-database azure-table-storage azure-data-factory

我正在尝试将表存储中的表格的精确副本复制到 Azure SQL

我的Source表(表存储)中的列存在问题,因为它可以有多种数据类型,在我的情况下为StringDateTime。仅当检索到的第一行中的 ArrivalTime 列具有DateTime数据类型时,才会出现此问题。据我所知,列的数据类型由第一条记录给出。 我在上面提到的情况下得到了以下错误,因为列中的其他String值无法转换为DateTime
在其他情况下,当第一行的列重新获得String DataType时,我没有任何问题,因为任何其他不同的数据类型都可以转换为String

AzureSql中的目标列设置为nvarchar,因此这不是问题。错误发生在源端

Copy activity encountered a user error at Source side:

错误讯息:

  

错误码= UserErrorInvalidDataValue, '类型= Microsoft.DataTransfer.Common.Shared.HybridDeliveryException,消息=列 'ArrivalTime' 包含一个无效值 'DateTime.Null',源= Microsoft.DataTransfer.Common,''类型=系统.ArgumentException,Message =指定的强制转换无效。不能存储在ArrivalTime列中。预期类型是DateTimeOffset。,Source = System.Data,''Type = System.InvalidCastException,Message =指定的强制转换无效。,Source = System.Data,'。

其他人是否遇到过这种情况? 有没有办法绕过这个问题?

由于

1 个答案:

答案 0 :(得分:1)

  

无法存储在ArrivalTime列中。预期类型是DateTimeOffset

您是否在表存储的日期集定义中定义了结构属性?如果您没有通过使用数据集定义中的结构属性来指定数据结构,则Data Factory将使用数据中的第一行来推断架构。虽然您在Azure SQL中将数据类型更改为nvarchar,但如果第一行中ArrivalTime的数据类型为DateTime,则来自源的ArrivalTime的日期类型也将被视为DateTime。

请将以下结构定义添加到Azure表存储的数据集中。

structure:  
[
    { "name": " ArrivalTime ", "type": "String"}
]

有关Azure数据工厂中数据集的详细信息,请参阅以下链接供您参考。

Datasets in Azure Data Factory

  

我已经在输入数据集和输出数据集中定义了这样的结构

抱歉提供了错误的指示。我测试了ADF Copy,然后是你的帖子,我再现了这个问题。该问题与ADF如何从Azure表存储中读取数据的机制有关。我还没有找到解决这个问题的方法。

  

有没有办法绕过这个问题?

如果您熟悉编程,则可以使用Azure WebJob或Azure Function轻松实现复制功能。在WebJob或Function中,您可以使用以下代码从Azure表存储中读取数据并将数据写入Azure SQL。

// Parse the connection string and return a reference to the storage account.
CloudStorageAccount storageAccount = CloudStorageAccount.Parse("Azure Storage Connection String");
// Create the table client.
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
// Retrieve a reference to the table.
CloudTable table = tableClient.GetTableReference("table name");

TableQuery<MyTableEntity> query = new TableQuery<MyTableEntity>();
// Loop all the entities of Azure Table and insert into Azure SQL
foreach (MyTableEntity entity in table.ExecuteQuery(query))
{
    using (SqlConnection connection = new SqlConnection("connection string of azure sql"))
    {
        SqlCommand cmd = new SqlCommand("insert into tables (ArrivalTime) values (@ArrivalTime) ", connection);
        cmd.Parameters.AddWithValue("ArrivalTime", entity.ArrivalTime);
        connection.Open();
        cmd.ExecuteNonQuery();
    }
}
public class MyTableEntity : TableEntity
{
    public MyTableEntity(string pkey, string rkey)
    {
        this.PartitionKey = pkey;
        this.RowKey = rkey;
    }

    public MyTableEntity() { }

    public string PKey { get; set; }

    public string RKey { get; set; }

    public string ArrivalTime { get; set; }
}