PageSourceSearch

https://apps-cookbook.dev/assets/js/117a82d8.0156a83e.js

js apps-cookbook.dev collected 2026-10-03 19:59:06 UTC 7,732 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkdocs=self.webpackChunkdocs||[]).push([[2119],{1294:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>i,default:()=>p,frontMatter:()=>o,metadata:()=>s,toc:()=>c});const s=JSON.parse('{"id":"reflex/tables/tables_read","title":"Read a Delta table","description":"This recipe reads a Unity Catalog table using the Databricks SQL Connector.","source":"@site/docs/reflex/tables/tables_read.mdx","sourceDirName":"reflex/tables","slug":"/reflex/tables/tables_read","permalink":"/docs/reflex/tables/tables_read","draft":false,"unlisted":false,"editUrl":"https://github.com/databricks-solutions/databricks-apps-cookbook/edit/main/docs/docs/reflex/tables/tables_read.mdx","tags":[],"version":"current","sidebarPosition":2,"frontMatter":{"sidebar_position":2},"sidebar":"tutorialSidebar","previous":{"title":"Connect an OLTP database","permalink":"/docs/reflex/tables/oltp_database_connect"},"next":{"title":"Edit a Delta table","permalink":"/docs/reflex/tables/tables_edit"}}');var a=t(4848),r=t(8453);const o={sidebar_position:2},i="Read a Delta table",l={},c=[{value:"Code snippet",id:"code-snippet",level:2},{value:"Resources",id:"resources",level:2},{value:"Permissions",id:"permissions",level:2},{value:"Dependencies",id:"dependencies",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",header:"header",li:"li",p:"p",pre:"pre",ul:"ul",...(0,r.R)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(n.header,{children:(0,a.jsx)(n.h1,{id:"read-a-delta-table",children:"Read a Delta table"})}),"\n",(0,a.jsxs)(n.p,{children:["This recipe reads a ",(0,a.jsx)(n.a,{href:"https://docs.databricks.com/aws/en/tables/",children:"Unity Catalog table"})," using the ",(0,a.jsx)(n.a,{href:"https://docs.databricks.com/en/dev-tools/python-sql-connector.html",children:"Databricks SQL Connector"}),"."]}),"\n",(0,a.jsx)(n.h2,{id:"code-snippet",children:"Code snippet"}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",metastring:'title="app.py"',children:'import reflex as rx\nfrom databricks import sql\nfrom databricks.sdk.core import Config\nimport logging\nimport pandas as pd\nfrom typing import Any\n\n_connection = None\n\n\ndef get_connection(http_path: str):\n    global _connection\n    if _connection:\n        return _connection\n    cfg = Config()\n    connection = sql.connect(\n        server_hostname=cfg.host,\n        http_path=http_path,\n        credentials_provider=cfg.authenticate,\n    )\n    _connection = connection\n    return connection\n\n\ndef read_table(table_name: str, conn) -> pd.DataFrame:\n    with conn.cursor() as cursor:\n        cursor.execute(f"SELECT * FROM {table_name}")\n        return cursor.fetchall_arrow().to_pandas()\n\n\ndef pandas_to_editor_format(\n    df: pd.DataFrame,\n) -> tuple[list[list[Any]], list[dict[str, str]]]:\n    """Convert a pandas DataFrame to the format required by rx.data_editor."""\n    if df.empty:\n        return ([], [])\n    data = df.values.tolist()\n    columns = [{"title": col, "id": col, "type": "str"} for col in df.columns]\n    return (data, columns)\n\n\nclass ReadTableState(rx.State):\n    http_path_input: str = ""\n    table_name: str = "samples.nyctaxi.trips"\n    df_data: list[list[Any]] = []\n    df_columns: list[dict] = []\n    is_loading: bool = False\n    error_message: str = ""\n\n    @rx.var\n    def columns_for_editor(self) -> list[dict]:\n        return self.df_columns\n\n    @rx.var\n    def data_for_editor(self) -> list[list[str]]:\n        """Return data directly as it is already formatted for the editor."""\n        return self.df_data\n\n    @rx.event(background=True)\n    async def load_table(self):\n        async with self:\n            self.is_loading = True\n            self.error_message = ""\n            self.df_data = []\n            self.df_columns = []\n            http_path = self.http_path_input\n            table_name = self.table_name\n        if not http_path:\n            async with self:\n                self.error_message = "Please enter an HTTP Path."\n                self.is_loading = False\n            return\n        try:\n            conn = get_connection(http_path)\n            df = read_table(table_name, conn)\n            data, cols = pandas_to_editor_format(df)\n            async with self:\n                self.df_data = data\n                self.df_columns = cols\n        except Exception as e:\n            logging.exception(f"Error loading Delta table: {e}")\n            async with self:\n                self.error_message = f"Error: {e}"\n        finally:\n            async with self:\n                self.is_loading = False\n'})}),"\n",(0,a.jsx)(n.admonition,{type:"info",children:(0,a.jsxs)(n.p,{children:["This sample caches the SQL connection in a module-level ",(0,a.jsx)(n.code,{children:"_connection"})," variable so it can be reused within the same app process. For multi-worker deployments, consider a proper pooling strategy or per-request connections depending on your workload."]})}),"\n",(0,a.jsx)(n.h2,{id:"resources",children:"Resources"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.databricks.
1com/aws/en/compute/sql-warehouse/",children:"SQL warehouse"})}),"\n",(0,a.jsx)(n.li,{children:(0,a.jsx)(n.a,{href:"https://docs.databricks.com/aws/en/tables/",children:"Unity Catalog table"})}),"\n"]}),"\n",(0,a.jsx)(n.h2,{id:"permissions",children:"Permissions"}),"\n",(0,a.jsxs)(n.p,{children:["Your ",(0,a.jsx)(n.a,{href:"https://docs.databricks.com/aws/en/dev-tools/databricks-apps/#how-does-databricks-apps-manage-authorization",children:"app service principal"})," needs the following permissions:"]}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"SELECT"})," on the Unity Catalog table"]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.code,{children:"CAN USE"})," on the SQL warehouse"]}),"\n"]}),"\n",(0,a.jsxs)(n.p,{children:["See Unity ",(0,a.jsx)(n.a,{href:"https://docs.databricks.com/aws/en/data-governance/unity-catalog/manage-privileges/privileges",children:"Catalog privileges and securable objects"})," for more information."]}),"\n",(0,a.jsx)(n.h2,{id:"dependencies",children:"Dependencies"}),"\n",(0,a.jsxs)(n.ul,{children:["\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://pypi.org/project/databricks-sdk/",children:"Databricks SDK"})," - ",(0,a.jsx)(n.code,{children:"databricks-sdk"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://pypi.org/project/databricks-sql-connector/",children:"Databricks SQL Connector"})," - ",(0,a.jsx)(n.code,{children:"databricks-sql-connector"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://pypi.org/project/pandas/",children:"Pandas"})," - ",(0,a.jsx)(n.code,{children:"pandas"})]}),"\n",(0,a.jsxs)(n.li,{children:[(0,a.jsx)(n.a,{href:"https://pypi.org/project/reflex/",children:"Reflex"})," - ",(0,a.jsx)(n.code,{children:"reflex"})]}),"\n"]}),"\n",(0,a.jsx)(n.pre,{children:(0,a.jsx)(n.code,{className:"language-python",metastring:'title="requirements.txt"',children:"databricks-sdk\ndatabricks-sql-connector\npandas\nreflex\n"})})]})}function p(e={}){const{wrapper:n}={...(0,r.R)(),...e.components};return n?(0,a.jsx)(n,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},8453:(e,n,t)=>{t.d(n,{R:()=>o,x:()=>i});var s=t(6540);const a={},r=s.createContext(a);function o(e){const n=s.useContext(r);return s.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function i(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:o(e.components),s.createElement(r.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.