Öğretici: Streamlit ile Databricks uygulaması geliştirme

Bu öğreticide, Python ve Streamlit için Databricks SQL Bağlayıcısı'nı kullanarak bir Databricks uygulamasının nasıl derleneceği gösterilmektedir. Aşağıdakileri yapacak bir uygulama geliştirmeyi öğreneceksiniz:

  • Unity Kataloğu tablosunu okur ve streamlit arabiriminde görüntüler.
  • Verileri düzenler ve tabloya geri yazar.

1. Adım: Ayrıcalıkları yapılandırma

Bu örneklerde uygulamanızın uygulama yetkilendirmesi kullandığı varsayılır. Uygulamanızın hizmet sorumlusu şu koşullara sahip olmalıdır:

  • SELECT Unity Kataloğu tablosu üzerinde yetki
  • MODIFY Unity Kataloğu tablosu üzerinde yetki
  • CAN USE SQL ambarında ayrıcalık

Daha fazla bilgi için Unity Kataloğu ayrıcalıkları referansı ve SQL ambarı ACL'leri kısımlarına bakın.

2. Adım: Bağımlılıkları yükleme

Bir requirements.txt dosya oluşturun ve aşağıdaki paketleri ekleyin:

databricks-sdk
databricks-sql-connector
streamlit
pandas

3. Adım: Uygulama yürütmeyi yapılandırma

Azure Databricks Apps'te uygulamanızın nasıl başlatılacağını tanımlamak için bir app.yaml dosya oluşturun.

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

4. Adım: Unity Kataloğu tablosunu okuma

Bu örnek kod, Unity Kataloğu tablosundaki verilerin nasıl okunduğunu ve Streamlit kullanılarak nasıl görüntüleneceğini gösterir. Aşağıdaki hedefleri karşılayan bir app.py dosya oluşturun:

  • Uygulama hizmet sorumlusu kimlik doğrulaması kullanır.
  • Kullanıcıdan SQL ambarı HTTP yolunu ve Unity Kataloğu tablo adını ister.
  • Belirtilen tabloda bir SELECT * sorgu yürütür.
  • Sonucu Streamlit st.dataframebiçiminde görüntüler.

app.py

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.")

5. Adım: Unity Kataloğu tablosunu düzenleme

Bu örnek kod, kullanıcıların Streamlit'in veri düzenleme özelliklerini kullanarak Unity Kataloğu tablosundaki değişiklikleri okumasına, düzenlemesine ve yazmasına olanak tanır. Dosyaya aşağıdaki işlevleri app.py ekleyin:

  • Güncelleştirilmiş verileri tabloya geri yazmak için kullanın INSERT OVERWRITE .

app.py

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.")

Sonraki Adımlar