Criar tabelas Delta
Ao criar uma tabela em um lakehouse do Microsoft Fabric, uma tabela Delta é definida no metastore para o lakehouse e os dados da tabela são armazenados nos arquivos Parquet subjacentes dela.
Com a maioria das ferramentas interativas no ambiente do Microsoft Fabric, os detalhes do mapeamento da definição de tabela no metastore para os arquivos subjacentes são abstraídos. No entanto, ao trabalhar com o Apache Spark em um lakehouse, você tem maior controle sobre a criação e o gerenciamento de tabelas Delta.
Criar uma tabela Delta com base em um dataframe
Uma das maneiras mais fáceis de criar uma tabela Delta no Spark é salvar um dataframe no formato delta. Por exemplo, o código PySpark a seguir carrega um dataframe com dados de um arquivo existente e o salva como uma tabela Delta:
# Load a file into a dataframe
df = spark.read.load('Files/mydata.csv', format='csv', header=True)
# Save the dataframe as a delta table
df.write.format("delta").saveAsTable("mytable")
O código especifica que a tabela deve ser salva no formato delta com um nome de tabela especificado. Os dados da tabela são salvos em arquivos Parquet (independentemente do formato do arquivo de origem carregado no dataframe) na área de armazenamento Tabelas do lakehouse e uma pasta _delta_log contém os logs de transação da tabela. A tabela está listada na pasta Tabelas do lakehouse no painel Data Explorer.
Tabelas gerenciadas vs. externas
No exemplo anterior, o dataframe foi salvo como uma tabela gerenciada, o que significa que a definição de tabela no metastore e os arquivos de dados subjacentes são gerenciados pelo runtime do Spark para o lakehouse do Fabric. Excluir a tabela também exclui os arquivos subjacentes do local de armazenamento Tabelas do lakehouse.
Também é possível criar tabelas como tabelas externas, em que a definição de tabela relacional no metastore é mapeada para um local de armazenamento de arquivos alternativo. Por exemplo, o seguinte código cria uma tabela externa cujos dados são armazenados na pasta no local de armazenamento Arquivos do lakehouse:
df.write.format("delta").saveAsTable("myexternaltable", path="Files/myexternaltable")
Neste exemplo, a definição de tabela é criada no metastore (portanto, a tabela é listada na interface do usuário Tabelas do lakehouse), mas os arquivos de dados Parquet e os arquivos de log JSON da tabela são armazenados no local de armazenamento Arquivos (e serão ser mostrado no nó Arquivos no painel Explorador de lakehouse).
Também é possível especificar um caminho totalmente qualificado para um local de armazenamento, como este:
df.write.format("delta").saveAsTable("myexternaltable", path="abfss://my_store_url..../myexternaltable")
Excluir uma tabela externa do metastore do lakehouse não exclui os arquivos de dados associados.
Criar metadados da tabela
Embora seja comum criar uma tabela com base em dados existentes em um dataframe, geralmente há cenários em que você deseja criar uma definição de tabela no metastore que será preenchida com dados de outras maneiras. Há diversas maneiras de atingir esse objetivo.
Usar a API DeltaTableBuilder
A API DeltaTableBuilder permite escrever códigos Spark para criar uma tabela com base em suas especificações. Por exemplo, o código a seguir cria uma tabela com um nome e com colunas especificados.
from delta.tables import *
DeltaTable.create(spark) \
.tableName("products") \
.addColumn("Productid", "INT") \
.addColumn("ProductName", "STRING") \
.addColumn("Category", "STRING") \
.addColumn("Price", "FLOAT") \
.execute()
Usar o Spark SQL
Também é possível criar tabelas Delta usando a instrução CREATE TABLE
do Spark SQL, conforme mostrado neste exemplo:
%%sql
CREATE TABLE salesorders
(
Orderid INT NOT NULL,
OrderDate TIMESTAMP NOT NULL,
CustomerName STRING,
SalesTotal FLOAT NOT NULL
)
USING DELTA
O exemplo anterior cria uma tabela gerenciada. Também é possível criar uma tabela externa especificando um parâmetro LOCATION
, conforme mostrado aqui:
%%sql
CREATE TABLE MyExternalTable
USING DELTA
LOCATION 'Files/mydata'
Ao criar uma tabela externa, o esquema da tabela é determinado pelos arquivos Parquet que contêm os dados no local especificado. Essa abordagem pode ser útil quando você deseja criar uma definição de tabela que faz referência a dados que já foram salvos no formato delta ou com base em uma pasta na qual você espera ingerir dados no formato delta.
Salvar dados no formato delta
Até agora, você aprendeu a salvar um dataframe como uma tabela Delta (criando a definição do esquema de tabela no metastore e os arquivos de dados no formato delta) e criar a definição de tabela (que cria o esquema de tabela no metastore sem salvar arquivos de dados). Uma terceira possibilidade é salvar os dados no formato delta sem criar uma definição de tabela no metastore. Essa abordagem pode ser útil quando você deseja persistir os resultados das transformações de dados realizadas no Spark em um formato de arquivo sobre o qual é possível "sobrepor" posteriormente uma definição de tabela ou um processo diretamente usando a API do Delta Lake.
Por exemplo, o seguinte código PySpark salva um dataframe em um novo local de pasta no formato delta:
delta_path = "Files/mydatatable"
df.write.format("delta").save(delta_path)
Os arquivos Delta são salvos no formato Parquet no caminho especificado e incluem uma pasta _delta_log que contém arquivos de alterações. Os arquivos de alterações registram quaisquer alterações nos dados, como atualizações feitas em tabelas externas ou por meio da API do delta lake.
É possível substituir o conteúdo de uma pasta existente com os dados em um dataframe usando o modo de substituição, conforme mostrado aqui:
new_df.write.format("delta").mode("overwrite").save(delta_path)
Também é possível adicionar linhas de um dataframe a uma pasta existente usando o modo de acréscimo:
new_rows_df.write.format("delta").mode("append").save(delta_path)
Dica
Se você usar a técnica descrita aqui para salvar um dataframe no local Tabelas do lakehouse, o Microsoft Fabric usará um recurso de descoberta automática de tabela para criar os metadados de tabela correspondentes no metastore.