У меня есть связанная рабочая область CosmosDb и Synapse. Почти все работает с использованием Synapse для создания SQL-представлений для данных Cosmos.
В Cosmos у меня есть один набор данных со свойством, которое всегда равно нулю. Я знаю, что на самом деле это десятичная дробь, потому что это цена, а будущие данные, вероятно, будут содержать десятичные цены.
В Synapse мне нужно проецировать эти данные в представление SQL, где этот столбец является правильным десятичным числом (19,4).
Когда я запускаю запрос OpenRowSet к данным Cosmos и пытаюсь указать тип для этого свойства, я получаю следующую ошибку.
select *
from OPENROWSET(
'CosmosDb',
'account=myaccount;database=myDatabase;region=theRegion;key=xxxxxxxxxxxxxxx',
[myCollection])
with (
[salesPrice] float '$.salesPrice')
as testQuery
Я получаю сообщение об ошибке:
Column 'salesPrice' of type 'FLOAT' is not compatible with external data type 'Parquet physical type: INT64', please try with 'BIGINT'.
Очевидно, что BIGINT здесь потерпит неудачу, как только я получу истинную десятичную цену.
Я думаю, что тип паркета устанавливается на BIGINT
, потому что в Cosmos все значения для этого столбца равны нулю. Я предполагаю, что в более общем плане была бы та же проблема, если бы свойство Cosmos было целым числом, отличным от нуля.
Как я могу заставить тип salesPrice быть десятичным или плавающим?
(Я не хочу, чтобы здесь меня отслеживали по плавающей и десятичной дробям для денежных значений, я понимаю разницу; эта ошибка возникает в любом случае)
Эта проблема проявляется и по-другому, без указания схемы с OPENROWSET
.
В новую коллекцию CosmosDb вставьте такой документ, как:
{
"myid" : 1,
"price" : 0
}
Если я подожду минуту или около того, я могу запросить этот документ из Synapse с помощью:
select *
from OPENROWSET(
'myCosmosDb',
'account=myAccount;database=myDatabase;region=myRegion;key=xxxxxxxxxxxxxxxxxxx',
[myCollection])
as testQuery;
и я получаю ожидаемые результаты.
Теперь добавьте второй документ:
{
"myid" : 1,
"price" : 1.1
}
и повторите запрос, и я получаю ту же ошибку:
Column 'price' of type 'FLOAT' is not compatible with external data type 'Parquet physical type: INT64', please try with 'BIGINT'
Есть ли способ обойти или предотвратить подобные ошибки?
Как насчет установить документ как
{
"myid" : "1",
"price" : "1.1"
}
Надеюсь, вы скоро решите это. В любом случае, я все же считаю, что изменение данных в строковом формате является наиболее удобным способом.
Долгое время возвращались к этому, но в конце концов мы решили преобразовать все данные json в строки, а затем вернуть в Synapse правильные типы данных. Итак, наконец, принято! Как ни странно, аналогичная проблема возникла с требованием конвертировать json в csv. Учитывая, что json не должен постоянно отображать все свойства (в отличие от csv), легко могут возникнуть несоответствия, если результаты csv необходимо объединить с существующими файлами csv. Более того, нам нужно было разбить вложенные массивы на отдельные файлы csv. Для всего этого требуется какая-то схема.
Данные не поступают из исходных систем в виде строк. Я предполагаю, что мы могли бы изменить все данные, поступающие в космос, на строки, но это не кажется очень удовлетворительным решением, равно как и заполнение коллекции в космосе явными типами. Проблема также может проявиться, если модели данных, поступающие в CosmosDb, изменились, и я хотел отредактировать схему паркета, чтобы отразить это изменение. Прямо сейчас я должен удалить всю коллекцию после резервного копирования данных, перезагрузить и перестроить в Synapse. У меня есть обращение в службу поддержки Azure по этому поводу, но без особых надежд.