> ## 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.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.omni.co/feedback

```json
{
  "path": "/guides/modeling/push-to-databricks-metric-views",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# 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 450 450" width="48" height="48">
                <defs>
                  <clipPath id="progressClip">
                    <rect x="0" y={450 - progress * 4.5} width="450" height={progress * 4.5} />
                  </clipPath>
                  <linearGradient id="blobbyGradient" x1="55.9753" y1="0" x2="492.197" y2="169.724" gradientUnits="userSpaceOnUse">
                    <stop stopColor="#BCA2F3" />
                    <stop offset="0.572917" stopColor="#FF7AA2" />
                    <stop offset="1" stopColor="#F3D4A2" />
                  </linearGradient>
                </defs>

                {}
                <circle cx="223.901" cy="223.901" r="213.901" transform="matrix(-0.999988 -0.0049013 0.00491945 -0.999988 447.797 449.992)" fill="#FAFAFA" stroke="#480B38" strokeWidth="20" />

                {}
                <circle cx="223.901" cy="223.901" r="213.901" transform="matrix(-0.999988 -0.0049013 0.00491945 -0.999988 447.797 449.992)" fill="url(#blobbyGradient)" stroke="#480B38" strokeWidth="20" clipPath="url(#progressClip)" />

                {}
                <path d="M310.41 195.084C310.41 200.052 301.362 212.472 284.328 212.472C266.585 212.472 258.246 201.294 258.246 195.912" stroke="#480B38" strokeWidth="17.3883" strokeMiterlimit="1.33344" strokeLinecap="round" />
                <circle cx="21.168" cy="21.168" r="21.168" transform="matrix(-1 0 0 1 388.658 169.001)" fill="#480B38" />
                <circle cx="21.168" cy="21.168" r="21.168" transform="matrix(-1 0 0 1 223.467 169.001)" fill="#480B38" />
              </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>
