Pular para o conteúdo principal

Tutorial: Desenvolva um aplicativo Databricks com o Streamlit

Este tutorial mostra como criar um aplicativo Databricks usando o Databricks SQL Connector para Python e Streamlit. Você aprenderá a desenvolver um aplicativo que faça o seguinte:

  • Lê uma tabela Unity Catalog e a exibe em uma interface Streamlit.
  • Edita os dados e os grava de volta na tabela.

o passo 1: Configurar privilégios

Esses exemplos pressupõem que seu aplicativo usa autorização de aplicativo. A entidade de serviço do seu aplicativo deve ter:

  • SELECT privilégio na tabela do Unity Catalog
  • MODIFY privilégio na tabela do Unity Catalog
  • CAN USE privilégio sobre o SQL warehouse

Para obter mais informações, consulte Unity Catalog privileges and securable objects e SQL warehouse ACLs.

o passo 2: Instalar dependências

Crie um arquivo requirements.txt e inclua o seguinte pacote:

Text
databricks-sdk
databricks-sql-connector
streamlit
pandas

o passo 3: Configurar a execução do aplicativo

Crie um arquivo app.yaml para definir como seu aplicativo inicia no Databricks Apps.

YAML
command: ['streamlit', 'run', 'app.py']

o passo 4: Leia uma tabela Unity Catalog

Este código de exemplo demonstra como ler dados de uma tabela do Unity Catalog e exibi-los usando o Streamlit. Crie um arquivo app.py que atenda aos seguintes objetivos:

  • Utiliza autenticação de entidade de serviço de aplicativo.
  • Solicita ao usuário o caminho HTTP do SQL warehouse e o nome da tabela do Unity Catalog.
  • Executa uma consulta SELECT * na tabela especificada.
  • Exibe o resultado em um Streamlit st.dataframe.

app.py

Python
import pandas as pd
import streamlit as st
from databricks import sql
from databricks.sdk.core import Config
import os

cfg = Config()

# Use app service principal authentication
def get_connection(http_path):
server_hostname = cfg.host
if server_hostname.startswith('https://'):
server_hostname = server_hostname.replace('https://', '')
elif server_hostname.startswith('http://'):
server_hostname = server_hostname.replace('http://', '')
return sql.connect(
server_hostname=server_hostname,
http_path=http_path,
credentials_provider=lambda: cfg.authenticate,
_use_arrow_native_complex_types=False,
)

# Read data from a Unity Catalog table and return it as a pandas DataFrame
def read_table(table_name: str, conn) -> pd.DataFrame:
with conn.cursor() as cursor:
cursor.execute(f"SELECT * FROM {table_name}")
return cursor.fetchall_arrow().to_pandas()

# Use Streamlit input fields to accept user input
http_path_input = st.text_input(
"Enter your Databricks HTTP Path:", placeholder="/sql/1.0/warehouses/xxxxxx"
)
table_name = st.text_input(
"Specify a Unity Catalog table name:", placeholder="catalog.schema.table"
)

# Display the result in a Streamlit DataFrame
if http_path_input and table_name:
conn = get_connection(http_path_input)
df = read_table(table_name, conn)
st.dataframe(df)
else:
st.warning("Provide both the warehouse path and a table name to load data.")

o passo 5: Editar uma tabela Unity Catalog

Este código de exemplo permite que os usuários leiam, editem e gravem alterações em uma tabela Unity Catalog usando o recurso de edição de dados do Streamlit. Adicione a seguinte funcionalidade ao arquivo app.py :

  • Use INSERT OVERWRITE para gravar os dados atualizados de volta na tabela.

app.py

Python
import pandas as pd
import streamlit as st
from databricks import sql
from databricks.sdk.core import Config
import math

cfg = Config()

# Use app service principal authentication
def get_connection(http_path):
server_hostname = cfg.host
if server_hostname.startswith('https://'):
server_hostname = server_hostname.replace('https://', '')
elif server_hostname.startswith('http://'):
server_hostname = server_hostname.replace('http://', '')
return sql.connect(
server_hostname=server_hostname,
http_path=http_path,
credentials_provider=lambda: cfg.authenticate,
_use_arrow_native_complex_types=False,
)

# Read data from a Unity Catalog table and return it as a pandas DataFrame
def read_table(table_name: str, conn) -> pd.DataFrame:
with conn.cursor() as cursor:
cursor.execute(f"SELECT * FROM {table_name}")
return cursor.fetchall_arrow().to_pandas()

# Format values for SQL, handling NaN/None as NULL
def format_value(val):
if val is None or (isinstance(val, float) and math.isnan(val)):
return 'NULL'
else:
return repr(val)

# Use `INSERT OVERWRITE` to update existing rows and insert new ones
def insert_overwrite_table(table_name: str, df: pd.DataFrame, conn):
progress = st.empty()
with conn.cursor() as cursor:
rows = list(df.itertuples(index=False))
values = ",".join([f"({','.join(map(format_value, row))})" for row in rows])
with progress:
st.info("Calling Databricks SQL...")
cursor.execute(f"INSERT OVERWRITE {table_name} VALUES {values}")
progress.empty()
st.success("Changes saved")

# Use Streamlit input fields to accept user input
http_path_input = st.text_input(
"Enter your Databricks HTTP Path:", placeholder="/sql/1.0/warehouses/xxxxxx"
)
table_name = st.text_input(
"Specify a Unity Catalog table name:", placeholder="catalog.schema.table"
)

# Display the result in a Streamlit DataFrame
if http_path_input and table_name:
conn = get_connection(http_path_input)
if conn:
st.success("✅ Connected successfully!")
original_df = read_table(table_name, conn)
edited_df = st.data_editor(original_df, num_rows="dynamic", hide_index=True)
df_diff = pd.concat([original_df, edited_df]).drop_duplicates(keep=False)
if not df_diff.empty:
st.warning(f"⚠️ You have {len(df_diff) // 2} unsaved changes")
if st.button("Save changes"):
insert_overwrite_table(table_name, edited_df, conn)
st.rerun()
else:
st.warning("Provide both the warehouse path and a table name to load data.")

Próximas etapas