Conector do Modelo de Dados Comum do Spark para o Azure Synapse Analytics

O conector Spark Common Data Model (conector Spark CDM) é um leitor/gravador de formato no Azure Synapse Analytics. Ele permite que um programa Spark leia e escreva entidades Common Data Model em uma pasta Common Data Model via Spark DataFrames.

Para obter informações sobre como definir documentos do Common Data Model usando o Common Data Model 1.2, consulte este artigo sobre o que é Common Data Model e como usá-lo.

Capacidades

Em um alto nível, o conector suporta:

  • 3.1, 3.2 e 3.3.
  • Leitura de dados de uma entidade em uma pasta Common Data Model em um Spark DataFrame.
  • Gravação de um Spark DataFrame para uma entidade em uma pasta Common Data Model com base em uma definição de entidade Common Data Model.
  • Gravação de um Spark DataFrame para uma entidade em uma pasta Common Data Model com base no esquema DataFrame.

O conector também suporta:

  • Leitura e gravação em pastas do Modelo de Dados Comum no Armazenamento do Azure Data Lake com um namespace hierárquico (HNS) habilitado.
  • Leitura de pastas Common Data Model descritas por arquivos manifest ou model.json .
  • Gravação em pastas Common Data Model descritas por um arquivo de manifesto.
  • Dados em formato CSV com ou sem cabeçalhos de coluna e com caracteres delimitadores selecionáveis pelo usuário.
  • Dados no formato Apache Parquet, incluindo Parquet aninhado.
  • Submanifestos na leitura e uso opcional de submanifestos com escopo de entidade na gravação.
  • Gravação de dados através de padrões de partição modificáveis pelo usuário.
  • Uso de identidades e credenciais gerenciadas no Azure Synapse Analytics.
  • Resolvendo locais de alias do Common Data Model usados em importações por meio das definições do adaptador Common Data Model descritas em um arquivo config.json .

Limitações

O conector não suporta os seguintes recursos e cenários:

  • Gravações paralelas. Não os recomendamos. Não há mecanismo de bloqueio na camada de armazenamento.
  • Acesso programático aos metadados da entidade depois de ler uma entidade.
  • Acesso programático para definir ou substituir metadados quando você estiver escrevendo uma entidade.
  • Desvio de esquema, onde os dados em um DataFrame que está sendo escrito incluem atributos extras não incluídos na definição de entidade.
  • Evolução do esquema, onde partições de entidade fazem referência a diferentes versões da definição de entidade. Você pode verificar a versão executando com.microsoft.cdm.BuildInfo.version.
  • Suporte de escrita para model.json.
  • Gravando Time dados no Parquet. Atualmente, o conector suporta a substituição de uma coluna de carimbo de data/hora para ser interpretado como um valor Common Data Model Time em vez de um DateTime valor apenas para arquivos CSV.
  • O tipo Parquet Map , matrizes de tipos primitivos e matrizes de tipos de matriz. Atualmente, o Common Data Model não oferece suporte a eles, assim como o conector Spark CDM.

Amostras

Para começar a usar o conector, confira o código de exemplo e os arquivos do Common Data Model.

Ler os dados

Quando o conector lê dados, ele usa metadados na pasta Common Data Model para criar o DataFrame com base na definição de entidade resolvida para a entidade especificada, conforme referenciado no manifesto. O conector usa nomes de atributos de entidade como nomes de coluna DataFrame. Ele mapeia tipos de dados de atributos para tipos de dados de coluna. Quando o DataFrame é carregado, ele é preenchido a partir das partições de entidade identificadas no manifesto.

O conector procura no manifesto especificado e em quaisquer submanifestos de primeiro nível para a entidade especificada. Se a entidade necessária estiver em um submanifesto de segundo nível ou inferior, ou se houver várias entidades do mesmo nome em submanifestos diferentes, especifique o submanifesto que contém a entidade necessária em vez do manifesto raiz.

As partições de entidade podem estar em uma combinação de formatos (por exemplo, CSV e Parquet). Todos os arquivos de dados de entidade identificados no manifesto são combinados em um conjunto de dados, independentemente do formato, e carregados para o DataFrame.

Quando o conector lê dados CSV, ele usa a opção Spark failfast por padrão. Se o número de colunas não for igual ao número de atributos na entidade, o conector retornará um erro.

Como alternativa, a partir de 0,19, o conector suporta o modo permissivo (apenas para arquivos CSV). Com o modo permissivo, quando uma linha CSV tem um número menor de colunas do que o esquema de entidade, o conector atribui valores nulos para as colunas ausentes. Quando uma linha CSV tem mais colunas do que o esquema de entidade, as colunas maiores do que a contagem de colunas do esquema de entidade são truncadas para a contagem de colunas do esquema. A utilização é a seguinte:

.option("mode", "permissive") or .option("mode", "failfast")

Gravando dados

Quando o conector grava em uma pasta Common Data Model, se a entidade ainda não existir nessa pasta, o conector cria uma nova entidade e definição. Ele adiciona a entidade e a definição à pasta Common Data Model e faz referência a elas no manifesto.

O conector suporta dois modos de escrita:

  • Gravação explícita: a definição de entidade física é baseada em uma definição lógica de entidade do Modelo de Dados Comum especificada por você.

    O conector lê e resolve a definição de entidade lógica especificada para criar a definição de entidade física usada na pasta Common Data Model. Se as instruções de importação em qualquer arquivo de definição do Common Data Model referenciado direta ou indiretamente incluírem aliases, você deverá fornecer um arquivo config.json que mapeie esses aliases para adaptadores e locais de armazenamento do Common Data Model.

    • Se o esquema DataFrame não corresponder à definição de entidade referenciada, o conector retornará um erro. Certifique-se de que os tipos de dados de coluna no DataFrame correspondam aos tipos de dados de atributo na entidade, incluindo dados decimais, precisão e escala definidos por meio de características no Common Data Model.
    • Se o DataFrame for inconsistente com a definição de entidade, o conector retornará um erro.
    • Se o DataFrame for consistente:
      • Se a entidade já existir no manifesto, o conector resolverá a definição de entidade fornecida e a validará em relação à definição na pasta Common Data Model. Se as definições não corresponderem, o conector retornará um erro. Caso contrário, o conector grava dados e atualiza as informações da partição no manifesto.
      • Se a entidade não existir na pasta Common Data Model, o conector gravará uma cópia resolvida da definição de entidade no manifesto na pasta Common Data Model. O conector grava dados e atualiza as informações da partição no manifesto.
  • Gravação implícita: A definição de entidade é derivada da estrutura DataFrame.

    • Se a entidade não existir na pasta Common Data Model, o conector usará a definição implícita para criar a definição de entidade resolvida na pasta Common Data Model de destino.

    • Se a entidade existir na pasta Common Data Model, o conector validará a definição implícita em relação à definição de entidade existente. Se as definições não corresponderem, o conector retornará um erro. Caso contrário, o conector grava dados e grava definições de entidade lógica derivadas em uma subpasta da pasta de entidade.

      O conector grava dados em pastas de dados dentro de uma subpasta de entidade. Um modo de salvamento determina se os novos dados sobrescrevem ou são acrescentados aos dados existentes, ou um erro é retornado se os dados existirem. O padrão é retornar um erro se os dados já existirem.

Integração de alias do Common Data Model

Os arquivos de definição do Modelo de Dados Comum usam aliases em instruções de importação para simplificar as instruções de importação e permitir que o local do conteúdo importado seja vinculado tardiamente em tempo de execução. Usando aliases:

  • Facilita a fácil organização de arquivos do Common Data Model para que as definições relacionadas do Common Data Model possam ser agrupadas em locais diferentes.
  • Permite que o conteúdo do Common Data Model seja acessado de diferentes locais implantados em tempo de execução.

O trecho a seguir mostra o uso de aliases em instruções de importação em um arquivo de definição do Common Data Model:

"imports": [  
{     
  "corpusPath": "cdm:/foundations.cdm.json"
},  
{       
  "corpusPath": "core:/TrackedEntity.cdm.json"  
},  
{      
  "corpusPath": "Customer.cdm.json"  
} 
]

O exemplo anterior usa cdm como um alias para o local do arquivo de fundações do Common Data Model. Ele usa core como um alias para o local do TrackedEntity arquivo de definição.

Aliases são rótulos de texto que correspondem a um valor de namespace em uma entrada de adaptador em um arquivo config.json do Common Data Model. Uma entrada de adaptador especifica o tipo de adaptador (por exemplo, , , GitHub, adlsCDNou local) e uma URL que define um local. Alguns adaptadores suportam outras opções de configuração, como um tempo limite de conexão. Enquanto os aliases são rótulos de texto arbitrários, o cdm alias é tratado de uma maneira especial.

O conector Spark CDM procura no local raiz do modelo da definição de entidade o arquivo config.json a ser carregado. Se o arquivo config.json estiver em algum outro local ou se você quiser substituir o arquivo config.json na raiz do modelo, poderá fornecer o local de um arquivo config.json usando a configPath opção. O arquivo config.json deve conter entradas do adaptador para todos os aliases usados no código do Common Data Model que está sendo resolvido ou o conector relata um erro.

A capacidade de substituir o arquivo config.json significa que você pode fornecer locais acessíveis em tempo de execução para definições do Common Data Model. Certifique-se de que o conteúdo referenciado em tempo de execução seja consistente com as definições que foram usadas quando o Common Data Model foi originalmente criado.

Por convenção, o alias refere-se ao local das definições padrão do Common Data Model de nível raiz, incluindo o cdmarquivo foundations.cdm.json . Esse arquivo inclui os tipos de dados primitivos Common Data Model e um conjunto principal de definições de características necessárias para a maioria das definições de entidade Common Data Model.

Você pode resolver o cdm alias como qualquer outro alias, usando uma entrada de adaptador no arquivo config.json . Se você não especificar um adaptador ou fornecer uma entrada nula, o cdm alias será resolvido por padrão para a CDN (rede de distribuição de conteúdo público) Common Data Model em https://cdm-schema.microsoft.com/logical/.

Você também pode usar a cdmSource opção para substituir como o cdm alias é resolvido. Usar a opção é útil se o alias for o cdm único alias usado nas definições do Common Data Model que estão sendo resolvidas, pois pode evitar a cdmSource necessidade de criar ou fazer referência a um arquivo config.json.

Parâmetros, opções e modo de gravação

Para leituras e gravações, você fornece o nome da biblioteca do conector Spark CDM como um parâmetro. Você usa um conjunto de opções para parametrizar o comportamento do conector. Quando você está escrevendo, o conector também suporta um modo de salvamento.

O nome da biblioteca do conector, as opções e o modo de gravação são formatados da seguinte forma:

  • dataframe.read.format("com.microsoft.cdm") [.option("option", "value")]*
  • dataframe.write.format("com.microsoft.cdm") [.option("option", "value")]* .mode(savemode.\<saveMode\>)

Aqui está um exemplo que mostra algumas das opções no uso do conector para leituras:

val readDf = spark.read.format("com.microsoft.cdm")
  .option("storage", "mystorageaccount.dfs.core.windows.net")
  .option("manifestPath", "customerleads/default.manifest.cdm.json")
  .option("entity", "Customer")
  .load()

Opções comuns de leitura e escrita

As opções a seguir identificam a entidade na pasta Common Data Model na qual você está lendo ou gravando.

Opção Descrição Padrão e exemplo de uso
storage A URL do ponto de extremidade para a conta do Armazenamento do Azure Data Lake, com HNS habilitado, que contém a pasta Common Data Model.
Use o dfs.core.windows.net URL.
<accountName>.dfs.core.windows.net "myAccount.dfs.core.windows.net"
manifestPath O caminho relativo para o manifesto ou arquivo model.json na conta de armazenamento. Para leituras, pode ser um manifesto raiz ou um submanifesto ou um arquivo model.json . Para gravações, deve ser um manifesto raiz. <container>/{<folderPath>}<manifestFileName>,
"mycontainer/default.manifest.cdm.json" "models/hr/employees.manifest.cdm.json"
"models/hr/employees/model.json" (somente leitura)
entity O nome da entidade de origem ou de destino no manifesto. Quando você está escrevendo uma entidade pela primeira vez em uma pasta, o conector dá esse nome à definição de entidade resolvida. O nome da entidade diferencia maiúsculas de minúsculas. <entityName>
"customer"
maxCDMThreads O número máximo de leituras simultâneas enquanto o conector resolve uma definição de entidade. Qualquer número inteiro válido, como 5

Nota

Não é mais necessário especificar uma definição de entidade lógica além da definição de entidade física na pasta Common Data Model na leitura.

Opções de escrita explícitas

As opções a seguir identificam a definição de entidade lógica para a entidade que está sendo escrita. A definição de entidade lógica é resolvida para uma definição física que define como a entidade é escrita.

Opção Descrição Padrão ou exemplo de uso
entityDefinitionStorage A conta do Armazenamento do Azure Data Lake que contém a definição de entidade. Necessário se for diferente da conta de armazenamento que hospeda a pasta Common Data Model. <accountName>.dfs.core.windows.net
"myAccount.dfs.core.windows.net"
entityDefinitionModelRoot A localização da raiz ou corpus do modelo dentro da conta. <container>/<folderPath>
"crm/core"
entityDefinitionPath A localização da entidade. É o caminho do arquivo para o arquivo de definição Common Data Model relativo à raiz do modelo, incluindo o nome da entidade nesse arquivo. <folderPath>/<entityName>.cdm.json/<entityName>
"sales/customer.cdm.json/customer"
configPath O caminho do contêiner e da pasta para um arquivo config.json que contém as configurações do adaptador para todos os aliases incluídos no arquivo de definição de entidade e quaisquer arquivos Common Data Model referenciados direta ou indiretamente.

Esta opção não é necessária se config.json estiver na pasta raiz do modelo.
<container><folderPath>
useCdmStandardModelRoot Indica que a raiz do modelo está localizada em https://cdm-schema.microsoft.com/CDM/logical/. Usado para fazer referência a tipos de entidade definidos na CDN do Common Data Model. Substitui entityDefinitionStorage e entityDefinitionModelRoot (se especificado).
"useCdmStandardModelRoot"
cdmSource Define como o cdm alias (se estiver presente em arquivos de definição do Common Data Model) é resolvido. Se você usar essa opção, ela substituirá qualquer cdm adaptador especificado no arquivo config.json . Os valores são builtin ou referenced. O valor predefinido é referenced.

Se você definir essa opção como referenced, o conector usará as definições padrão do Common Data Model publicadas mais recentes em https://cdm-schema.microsoft.com/logical/. Se você definir essa opção como builtin, o conector usará as definições de base do Common Data Model incorporadas ao modelo de objeto Common Data Model que o conector está usando.

Observação:
* O conector Spark CDM pode não estar usando o SDK do Common Data Model mais recente, portanto, pode não conter as definições padrão publicadas mais recentes.
* As definições internas incluem apenas o conteúdo do Common Data Model de nível superior, como foundations.cdm.json ou primitives.cdm.json. Se você quiser usar definições padrão de modelo de dados comuns de nível inferior, use referenced ou inclua um cdm adaptador em config.json.
"builtin"|"referenced"

No exemplo anterior, o caminho completo para o objeto de definição de entidade do cliente é https://myAccount.dfs.core.windows.net/models/crm/core/sales/customer.cdm.json/customer. Nesse caminho, modelos é o contêiner no Armazenamento do Azure Data Lake.

Opções de escrita implícitas

Se você não especificar uma definição de entidade lógica na gravação, a entidade será escrita implicitamente, com base no esquema DataFrame.

Quando você está escrevendo implicitamente, uma coluna de carimbo de data/hora é normalmente interpretada como um tipo de dados Common Data Model DateTime . Você pode substituir essa interpretação para criar um atributo do tipo de dados Common Data Model Time fornecendo um objeto de metadados associado à coluna que especifica o tipo de dados. Para obter detalhes, consulte Manipulando dados de tempo do Modelo de Dados Comum mais adiante neste artigo.

O suporte para dados de tempo de gravação existe apenas para arquivos CSV. Esse suporte atualmente não se estende ao Parquet.

Opções de estrutura de pastas e formato de dados

Você pode usar as seguintes opções para alterar a organização da pasta e o formato do arquivo.

Opção Descrição Padrão ou exemplo de uso
useSubManifest If true, faz com que a entidade de destino seja incluída no manifesto raiz por meio de um submanifesto. O submanifesto e a definição de entidade são gravados em uma pasta de entidade abaixo da raiz. A predefinição é false. "true"|"false"
format Define o formato do arquivo. Os formatos de arquivo suportados atualmente são CSV e Parquet. A predefinição é csv. "csv"|"parquet"
delimiter Apenas CSV. Define o delimitador que você está usando. O padrão é vírgula. "|"
columnHeaders Apenas CSV. Se true, adiciona uma primeira linha aos arquivos de dados com cabeçalhos de coluna. A predefinição é true. "true"|"false"
compression Apenas escrita. Apenas parquet. Define o formato de compactação que você está usando. A predefinição é snappy. "uncompressed" | "snappy" | "gzip" | "lzo"
dataFolderFormat Permite uma estrutura de pastas de dados definível pelo usuário dentro de uma pasta de entidade. Permite substituir valores de data e hora em nomes de pastas usando DateTimeFormatter formatação. O conteúdo que não seja formatador deve ser colocado entre aspas simples. O formato padrão é "yyyy"-"MM"-"dd", que produz nomes de pastas como 2020-07-30. year "yyyy" / month "MM"
"Data"

Modo de guardar

O modo de salvamento especifica como o conector lida com dados de entidade existentes na pasta Common Data Model quando você está escrevendo um DataFrame. As opções são substituir, acrescentar ou retornar um erro se os dados já existirem. O modo de gravação padrão é ErrorIfExists.

Modo Descrição
SaveMode.Overwrite Substitui a definição de entidade existente se ela for alterada e substitui as partições de dados existentes pelas partições de dados que estão sendo gravadas.
SaveMode.Append Acrescenta dados que estão sendo gravados em novas partições ao lado das partições existentes.

Este modo não suporta a alteração do esquema. Se o esquema dos dados que estão sendo gravados for incompatível com a definição de entidade existente, o conector lançará um erro.
SaveMode.ErrorIfExists Retorna um erro se as partições já existirem.

Para obter detalhes de como os arquivos de dados são nomeados e organizados na gravação, consulte a seção Nomenclatura e organização de pastas e arquivos mais adiante neste artigo.

Autenticação

Você pode usar três modos de autenticação com o conector Spark CDM para ler ou gravar os metadados e partições de dados do Common Data Model: passagem de credenciais, token de assinatura de acesso compartilhado (SAS) e registro de aplicativo.

Pass-through de credenciais

No Azure Synapse Analytics, o conector Spark CDM dá suporte ao uso de identidades gerenciadas para recursos do Azure para mediar o acesso à conta de Armazenamento do Azure Data Lake que contém a pasta Common Data Model. Uma identidade gerenciada é criada automaticamente para cada espaço de trabalho do Azure Synapse Analytics. O conector usa a identidade gerenciada do espaço de trabalho que contém o bloco de anotações no qual o conector é chamado para autenticar as contas de armazenamento.

Você deve garantir que a identidade escolhida tenha acesso às contas de armazenamento apropriadas:

  • Conceda permissões de Colaborador de Dados de Blob de Armazenamento para permitir que a biblioteca grave em pastas do Modelo de Dados Comum.
  • Conceda permissões de Leitor de Dados de Blob de Armazenamento para permitir apenas acesso de leitura.

Em ambos os casos, não são necessárias opções de conector extra.

Opções para controle de acesso baseado em token SAS

As credenciais do token SAS são uma opção extra para autenticação em contas de armazenamento. Com a autenticação de token SAS, o token SAS pode estar no nível de contêiner ou pasta. As permissões apropriadas são necessárias:

  • As permissões de leitura para um manifesto ou partição precisam apenas de suporte de nível de leitura.
  • As permissões de gravação precisam de suporte de leitura e gravação.
Opção Descrição Padrão e exemplo de uso
sasToken O token SAS para acessar a conta de armazenamento relativa com as permissões corretas <token>

Opções para controle de acesso baseado em credenciais

Como alternativa ao uso de uma identidade gerenciada ou de usuário, você pode fornecer credenciais explícitas para habilitar o conector CDM do Spark para acessar dados. No Microsoft Entra ID, crie um registro de aplicativo. Em seguida, conceda a este aplicativo acesso de registro à conta de armazenamento usando uma das seguintes funções:

  • Contribuidor de Dados de Blob de Armazenamento para permitir que a biblioteca grave em pastas do Modelo de Dados Comum
  • Leitor de dados de Blob de armazenamento para permitir apenas permissões de leitura

Depois de criar permissões, você pode passar a ID do aplicativo, a chave do aplicativo e a ID do locatário para o conector em cada chamada usando as opções a seguir. Recomendamos que você use o Azure Key Vault para armazenar esses valores para garantir que eles não sejam armazenados em texto não criptografado em seu arquivo de bloco de anotações.

Opção Descrição Padrão e exemplo de uso
appId O ID de registro do aplicativo para autenticação na conta de armazenamento <guid>
appKey A chave ou segredo da aplicação registada <encrypted secret>
tenantId A ID de locatário do Microsoft Entra sob a qual o aplicativo está registrado <guid>

Exemplos

Todos os exemplos a seguir usam appId, appKeye tenantId variáveis. Você inicializou essas variáveis anteriormente no código, com base em um registro de aplicativo do Azure: permissões de Colaborador de Dados de Blob de Armazenamento no armazenamento para gravação e permissões de Leitor de Dados de Blob de Armazenamento para leitura.

Lida

Este código lê a Person entidade da pasta Common Data Model com um manifesto em mystorage.dfs.core.windows.net/cdmdata/contacts/root.manifest.cdm.json:

val df = spark.read.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/contacts/root.manifest.cdm.json")
 .option("entity", "Person")
 .load()

Gravação implícita usando apenas um esquema DataFrame

O código a seguir grava o df DataFrame em uma pasta Common Data Model com um manifesto para mystorage.dfs.core.windows.net/cdmdata/Contacts/default.manifest.cdm.json com uma entidade de evento.

O código grava dados de eventos como arquivos Parquet, compacta-os com gzipe os acrescenta à pasta. (O código adiciona novos arquivos sem excluir arquivos existentes.)


df.write.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/Contacts/default.manifest.cdm.json")
 .option("entity", "Event")
 .option("format", "parquet")
 .option("compression", "gzip")
 .mode(SaveMode.Append)
 .save()

Gravação explícita usando uma definição de entidade armazenada no Armazenamento Data Lake

O código a seguir grava o df DataFrame em uma pasta Common Data Model com um manifesto em https://_mystorage_.dfs.core.windows.net/cdmdata/Contacts/root.manifest.cdm.json com a Person entidade. O código grava dados pessoais como novos arquivos CSV (por padrão) que substituem arquivos existentes na pasta.

O código recupera a Person definição de entidade de https://_mystorage_.dfs.core.windows.net/models/cdmmodels/core/Contacts/Person.cdm.json.

df.write.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/contacts/root.manifest.cdm.json")
 .option("entity", "Person")
 .option("entityDefinitionModelRoot", "cdmmodels/core")
 .option("entityDefinitionPath", "/Contacts/Person.cdm.json/Person")
 .mode(SaveMode.Overwrite)
 .save()

Gravação explícita usando uma entidade definida no repositório GitHub do Common Data Model

O código a seguir grava o df DataFrame em uma pasta Common Data Model com:

  • O manifesto em https://_mystorage_.dfs.core.windows.net/cdmdata/Teams/root.manifest.cdm.json.
  • Um submanifesto que contém a TeamMembership entidade criada em um subdiretório TeamMembership .

TeamMembership os dados são gravados em arquivos CSV (o padrão) que substituem quaisquer arquivos de dados existentes. O código recupera a TeamMembership definição de entidade da CDN do Common Data Model em https://cdm-schema.microsoft.com/logical/core/applicationCommon/TeamMembership.cdm.json.

df.write.format("com.microsoft.cdm")
 .option("storage", "mystorage.dfs.core.windows.net")
 .option("manifestPath", "cdmdata/Teams/root.manifest.cdm.json")
 .option("entity", "TeamMembership")
 .option("useCdmStandardModelRoot", true)
 .option("entityDefinitionPath", "core/applicationCommon/TeamMembership.cdm.json/TeamMembership")
 .option("useSubManifest", true)
 .mode(SaveMode.Overwrite)
 .save()

Outras considerações

Mapeando tipos de dados do Spark para o Common Data Model

O conector aplica os seguintes mapeamentos de tipo de dados quando você converte o Common Data Model para ou do Spark.

Spark Common Data Model
ShortType SmallInteger
IntegerType Integer
LongType BigInteger
DateType Date
Timestamp DateTime (opcionalmente Time)
StringType String
DoubleType Double
DecimalType(x,y) Decimal (x,y) (escala e precisão padrão são 18,4)
FloatType Float
BooleanType Boolean
ByteType Byte

O conector não suporta o tipo de dados Common Data Model Binary .

Manipulando dados comuns de Data Model Date, DateTime e DateTimeOffset

O conector Spark CDM lida com o Common Data Model Date e os tipos de dados como normal para o Spark e DateTime o Parquet. No CSV, o conector lê e grava esses tipos de dados no formato ISO 8601.

O conector interpreta os valores do tipo de dados Common Data Model DateTime como UTC. No CSV, o conector grava esses valores no formato ISO 8601. Um exemplo é 2020-03-13 09:49:00Z.

Os valores comuns do Modelo DateTimeOffset de Dados destinados ao registro de instantes de hora local são tratados de forma diferente no Spark e no Parquet do CSV. CSV e outros formatos podem expressar um instante de hora local como uma estrutura que compreende uma data/hora, como 2020-03-13 09:49:00-08:00. Parquet e Spark não suportam essas estruturas. Em vez disso, eles usam um tipo de dados que permite que um instante seja gravado em UTC (ou em um TIMESTAMP fuso horário não especificado).

O conector Spark CDM converte um valor em CSV em um DateTimeOffset carimbo de data/hora UTC. Esse valor é mantido como um carimbo de data/hora no Parquet. Se o valor for posteriormente persistido para CSV, ele será serializado como um valor com um DateTimeOffset deslocamento +00:00. Não há perda de precisão temporal. Os valores serializados representam o mesmo instante que os valores originais, embora o deslocamento seja perdido.

Os sistemas Spark usam a hora do sistema como linha de base e normalmente expressam a hora usando essa hora local. Os tempos UTC podem sempre ser calculados através da aplicação do deslocamento do sistema local. Para sistemas Azure em todas as regiões, a hora do sistema é sempre UTC, portanto, todos os valores de carimbo de data/hora normalmente estão em UTC. Quando você estiver usando uma gravação implícita, em que uma definição de Modelo de Dados Comum é derivada de um DataFrame, as colunas de carimbo de data/hora são convertidas em atributos com o tipo de dados Modelo de Dados DateTime Comum, o que implica uma hora UTC.

Se for importante persistir uma hora local e os dados forem processados no Spark ou persistidos no Parquet, recomendamos que você use um atributo e mantenha o deslocamento em um DateTime atributo separado. Por exemplo, você pode manter o deslocamento como um valor inteiro assinado que representa minutos. No Common Data Model, os valores DateTime estão em UTC, portanto, você deve aplicar o deslocamento para calcular a hora local.

Na maioria dos casos, persistir a hora local não é importante. As horas locais geralmente são necessárias apenas em uma interface do usuário para conveniência do usuário e com base no fuso horário do usuário, portanto, não armazenar uma hora UTC geralmente é uma solução melhor.

Manipulando dados de tempo do Modelo de Dados Comum

O Spark não suporta um tipo de dados explícito Time . Um atributo com o tipo de dados Common Data Model Time é representado em um Spark DataFrame como uma coluna com um tipo de Timestamp dados. Quando o conector Spark CDM lê um valor de hora, o carimbo de data/hora no DataFrame é inicializado com a data de época do Spark 01/01/1970 mais o valor de tempo conforme lido da fonte.

Ao usar a gravação explícita, você pode mapear uma coluna de carimbo de data/hora para um DateTime ou Time atributo. Se você mapear um carimbo de data/hora para um Time atributo, a parte de data do carimbo de data/hora será removida.

Quando você usa gravação implícita, uma coluna de carimbo de data/hora é mapeada por padrão para um DateTime atributo. Para mapear uma coluna de carimbo de data/hora para um atributo, você deve adicionar um objeto de metadados à coluna no DataFrame que indica que o carimbo de data/hora deve ser interpretado como um Time valor de data/hora. O código a seguir mostra como fazer isso no Scala:

val md = new MetadataBuilder().putString(“dataType”, “Time”)
val schema = StructType(List(
StructField(“ATimeColumn”, TimeStampType, true, md))

Precisão do valor de tempo

O conector Spark CDM suporta valores de tempo em ou DateTimeTime. Os segundos têm até seis casas decimais, com base no formato dos dados no arquivo que está sendo lido (CSV ou Parquet) ou conforme definido no DataFrame. O uso de seis casas decimais permite a precisão de um único segundo a microssegundos.

Nomenclatura e organização de pastas e arquivos

Quando você está gravando em pastas Common Data Model, há uma organização de pasta padrão. Por padrão, os arquivos de dados são gravados em pastas criadas para a data atual, nomeadas como 2010-07-31. Você pode personalizar a estrutura de pastas e os nomes usando a dateFolderFormat opção.

Os nomes dos arquivos de dados são baseados no seguinte padrão: <entity-jobid>>-<*.<formato> de ficheiro.

Você pode controlar o número de partições de dados que são escritas usando o sparkContext.parallelize() método. O número de partições é determinado pelo número de executores no cluster Spark ou especificado explicitamente. O exemplo de Scala a seguir cria um DataFrame com duas partições:

val df= spark.createDataFrame(spark.sparkContext.parallelize(data, 2), schema)

Aqui está um exemplo de uma escrita explícita definida por uma definição de entidade referenciada:

+-- <CDMFolder>
     |-- default.manifest.cdm.json     << with entity reference and partition info
     +-- <Entity>
          |-- <entity>.cdm.json        << resolved physical entity definition
          |-- <data folder>
          |-- <data folder>
          +-- ...                            

Aqui está um exemplo de uma escrita explícita com um submanifesto:

+-- <CDMFolder>
    |-- default.manifest.cdm.json       << contains reference to submanifest
    +-- <Entity>
         |-- <entity>.cdm.json
         |-- <entity>.manifest.cdm.json << submanifest with partition info
         |-- <data folder>
         |-- <data folder>
         +-- ...

Aqui está um exemplo de uma gravação implícita na qual a definição de entidade é derivada de um esquema DataFrame:

+-- <CDMFolder>
    |-- default.manifest.cdm.json
    +-- <Entity>
         |-- <entity>.cdm.json          << resolved physical entity definition
         +-- LogicalDefinition
         |   +-- <entity>.cdm.json      << logical entity definitions
         |-- <data folder>
         |-- <data folder>
         +-- ...

Aqui está um exemplo de uma escrita implícita com um submanifesto:

+-- <CDMFolder>
    |-- default.manifest.cdm.json       << contains reference to submanifest
    +-- <Entity>
        |-- <entity>.cdm.json           << resolved physical entity definition
        |-- <entity>.manifest.cdm.json  << submanifest with reference to the entity and partition info
        +-- LogicalDefinition
        |   +-- <entity>.cdm.json       << logical entity definitions
        |-- <data folder>
        |-- <data folder>
        +-- ...

Resolução de problemas e problemas conhecidos

  • Verifique se a precisão decimal e a escala dos campos de tipo de dados decimais que você usa no DataFrame correspondem ao tipo de dados que está na definição de entidade Common Data Model. Se a precisão e a escala não estiverem definidas explicitamente no Common Data Model, o padrão será Decimal(18,4). Para arquivos model.json , Decimal presume-se que seja Decimal(18,4).
  • Os nomes de pastas e arquivos nas opções a seguir não devem incluir espaços ou caracteres especiais, como um sinal de igual (=): manifestPath, , , dataFolderFormatentityDefinitionModelRootentityDefinitionPath.

Próximos passos

Agora você pode olhar para os outros conectores Apache Spark: