我正在尝试将表存储中的表格的精确副本复制到 Azure SQL 。
我的Source表(表存储)中的列存在问题,因为它可以有多种数据类型,在我的情况下为String
或DateTime
。仅当检索到的第一行中的 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,'。
其他人是否遇到过这种情况? 有没有办法绕过这个问题?
由于
答案 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; }
}