> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omni.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Push Omni topics to Databricks as metric views

> Use the Omni Python SDK to generate Databricks metric view DDL from an Omni topic.

export const categoryIcons = {
  'administration': 'lock',
  'api': 'terminal',
  'connections': 'database',
  'dashboards': 'table-columns',
  'embed': 'code',
  'errors': 'exclamation',
  'modeling': 'wrench',
  'patterns': 'plus',
  'schedules & alerts': 'envelope',
  'visualizations': 'chart-column',
  'workbooks': 'book'
};

export const GuideSidebar = ({category, relatedLinks, updatedDate}) => {
  const [progress, setProgress] = React.useState(0);
  React.useEffect(() => {
    const sidebar = document.querySelector('.guide-sidebar');
    if (!sidebar) return;
    let container = sidebar.parentElement;
    while (container && !container.querySelector('.guide-header')) {
      container = container.parentElement;
    }
    if (container && !container.classList.contains('guide-page-layout')) {
      container.classList.add('guide-page-layout');
    }
  }, []);
  React.useEffect(() => {
    const handleScroll = () => {
      const scrollTop = window.scrollY;
      const docHeight = document.documentElement.scrollHeight - window.innerHeight;
      const scrollPercent = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
      setProgress(Math.min(100, Math.max(0, scrollPercent)));
    };
    window.addEventListener('scroll', handleScroll, {
      passive: true
    });
    handleScroll();
    return () => window.removeEventListener('scroll', handleScroll);
  }, []);
  const icon = category ? categoryIcons[category.toLowerCase()] || 'book' : 'book';
  return <aside className="guide-sidebar">
      <div className="guide-sidebar-content">
        <a href="/guides" className="guide-sidebar-back">
          <Icon icon="arrow-left" iconType="solid" size={14} />
          <span>All guides</span>
        </a>

        <div className="guide-sidebar-section">
          <div className="guide-sidebar-label">Progress</div>
          <div className="guide-sidebar-progress">
            <div className="guide-mascot">
              <svg viewBox="0 0 688 690" width="48" height="48">
                <defs>
                  <clipPath id="progressClip">
                    <rect x="0" y={0} width="688" height={progress * 6.9} />
                  </clipPath>
                </defs>

                {}
                <path d="M343.67 1.5C542.684 1.5 685.84 149.351 685.84 344.84C685.84 540.328 542.685 688.18 343.67 688.18C144.655 688.18 1.5 540.318 1.5 344.84C1.50007 149.361 144.655 1.50005 343.67 1.5Z" fill="#FCFCF7" stroke="#FF5FA2" strokeWidth="3" />

                {}
                <path d="M343.67 0C143.81 0 0 148.55 0 344.84C0 541.13 143.81 689.68 343.67 689.68C543.53 689.68 687.34 541.14 687.34 344.84C687.34 148.54 543.53 0 343.67 0Z" fill="#FF5FA2" clipPath="url(#progressClip)" />

                {}
                <path d="M337.89 319.29C337.89 336.75 322.49 350.14 302.81 349.83C286.18 349.57 273.89 337.29 274.37 321.45C274.88 304.82 290.91 290.88 309.98 290.44C325.69 290.09 337.88 302.69 337.88 319.29H337.89Z" fill="#4D122C" />
                <path d="M566.17 319.29C566.17 336.75 550.77 350.14 531.09 349.83C514.46 349.57 502.17 337.29 502.65 321.45C503.16 304.82 519.19 290.88 538.26 290.44C553.97 290.09 566.16 302.69 566.16 319.29H566.17Z" fill="#4D122C" />
                <path d="M367.74 342.07C360.22 346.32 359.4 354.9 370.62 366.4C381.85 377.9 399.76 389.56 420.81 389.18C441.88 389.1 460.67 377.72 472.47 363.53C473.83 361.93 478.84 356.88 478.51 351.07C478.32 348.35 476.17 341.19 467.83 341.38C463.46 341.44 461.21 343.68 456.69 347.36C445.2 356.14 432.7 361.21 420.56 361.27C408.43 361.43 395.68 356.17 385.39 347.22C380.32 342.81 375.25 337.82 367.74 342.07Z" fill="#4D122C" />
              </svg>
            </div>
            <span className="guide-sidebar-progress-text">{Math.round(progress)}%</span>
          </div>
        </div>

        {category && <div className="guide-sidebar-section">
            <div className="guide-sidebar-label">Category</div>
            <div className="guide-sidebar-category">
              <Icon icon={icon} iconType="solid" size={14} />
              <span>{category}</span>
            </div>
          </div>}

        {updatedDate && <div className="guide-sidebar-section">
            <div className="guide-sidebar-label">Last updated</div>
            <div className="guide-sidebar-date">{updatedDate}</div>
          </div>}

        {relatedLinks && relatedLinks.length > 0 && <div className="guide-sidebar-section">
            <div className="guide-sidebar-label">Related</div>
            <ul className="guide-sidebar-links">
              {relatedLinks.map((link, index) => <li key={index}>
                  <a href={link.href}>{link.title}</a>
                </li>)}
            </ul>
          </div>}
      </div>
    </aside>;
};

export const GuideTitle = ({title}) => {
  return <div className="guide-header">
      <h1 className="guide-title">{title}</h1>
    </div>;
};

<GuideSidebar
  categoryIcons={categoryIcons}
  category="modeling"
  updatedDate="February 2026"
  relatedLinks={[
{ title: "Databricks Unity Catalog integration", href: "/connect-data/databricks-unity-catalog-integration" },
{ title: "Topics", href: "/modeling/topics" },
{ title: "Omni Python SDK", href: "https://github.com/exploreomni/omni-python-sdk" }
]}
/>

<GuideTitle title="Push Omni topics to Databricks as metric views" />

If you've built a [topic](/modeling/topics) in Omni that you want to formalize as a governed metric view in Databricks Unity Catalog, you can use the [Omni Python SDK](https://github.com/exploreomni/omni-python-sdk) to generate the required DDL.

The SDK fetches your topic definition from the Omni API, converts its dimensions and measures into Databricks' YAML-based metric view format, and outputs a `CREATE VIEW ... WITH METRICS` statement that you can run directly in Databricks.

## How it works

The script calls the Omni API endpoint [Retrieve a topic API](/api/topics/retrieve-a-topic) to retrieve the full topic definition, including its views, dimensions, measures, and relationships. It then:

1. Identifies the base view (fact table) and its fully qualified table name as the metric view source.
2. Maps each dimension and measure to the Databricks metric view YAML format, transforming Omni's `${field_name}` SQL references into Databricks-compatible syntax.
3. Wraps the YAML in a `CREATE OR REPLACE VIEW ... WITH METRICS LANGUAGE YAML` DDL statement.

## Requirements

* Python 3.9 or later. Additionally, this guide uses pip to install Python dependencies, but you can use a different package manager.
* A Databricks connection
* An [Omni API key](/api/authentication)
* Permissions in Omni that allow you to access the model you want to export
* The model ID and topic name for the topic you want to export

## Steps

<Steps>
  <Step title="Install the Omni Python SDK" titleSize="h3">
    1. In the terminal, clone the SDK repository and install its dependencies:

       ```bash theme={null}
       git clone https://github.com/exploreomni/omni-python-sdk.git
       cd omni-python-sdk
       pip install .
       ```

    2. Next, create a `.env` file in the SDK directory with your Omni [API key](/api/authentication) and [base URL](/api#base-url):

       ```bash theme={null}
       OMNI_API_KEY=your_api_key
       OMNI_BASE_URL=https://your-org.omni.co
       ```
  </Step>

  <Step title="Find your model ID and topic name" titleSize="h3">
    You'll need two values from Omni:

    * **Model ID**: Open the model IDE and copy the model ID from the URL. The model ID is the UUID in the URL after `/models`. In the following URL, for example, the model IDE is `abcd1234-5678-90ab-cdef-1234567890ab`:

      ```text theme={null}
      https://your-org.omni.co/ide/models/abcd1234-5678-90ab-cdef-1234567890ab`
      ```

    * **Topic name**: The name of the topic as it appears in the model, such as `order_items`.
  </Step>

  <Step title="Run the script" titleSize="h3">
    The SDK includes a script that fetches the topic definition and generates Databricks DDL. The script takes the following arguments:

    * `model_id` - **Required**. The ID of the Omni model.
    * `topic_id` - **Required**. The name of the topic you want to export.
    * `default_catalog` - **Optional**. The name of the Databricks catalog where you want to create the metric view.
    * `default_schema` - **Optional**. The name of the Databricks schema where you want to create the metric view.

    ```bash theme={null}
    python -m examples.databricks_metric_view <model_id> <topic_name> <default_catalog> <default_schema>
    ```

    Run the script from the SDK directory, for example:

    ```bash theme={null}
    python -m examples.databricks_metric_view abcd1234-5678-90ab-cdef-1234567890ab order_items my_catalog my_schema
    ```

    The script outputs a `CREATE OR REPLACE VIEW` statement with the topic's dimensions, measures, and source table formatted as a Databricks metric view.
  </Step>

  <Step title="Execute the DDL in Databricks" titleSize="h3">
    Copy the generated DDL and run it in your Databricks SQL console. This creates a new metric view in your Unity Catalog with the naming convention `OMNI__<topic_name>`. For example:

    ```sql title="Example generated DDL for Omni topic" theme={null}
    CREATE OR REPLACE VIEW `OMNI__order_items`
    WITH METRICS
    LANGUAGE YAML
    COMMENT 'Generated from Omni topic: order_items'
    AS $$
    version: '1.1'
    source: omni_demo.ecomm.ecomm__order_items
    dimensions:
    - name: Date
      expr: created_at

    measures:
    - name: Order_Transactions_Count
      expr: count(*)
    - name: ecomm__users_Users_Count
      expr: count(*)
    joins:
    - name: ecomm__users
      source: omni_demo.ecomm.ecomm__users
      on: source.user_id = ecomm__users.id

    $$
    ```

    Once created, the metric view is available in Databricks like any other Unity Catalog asset. If you have the [Unity Catalog integration enabled](/connect-data/databricks-unity-catalog-integration), the metric view will also sync back into Omni on the next schema refresh.
  </Step>
</Steps>
