From 7b5090d394e5a1b49643265f4cc7bd55af8ffffa Mon Sep 17 00:00:00 2001 From: Cortland Goffena <30168413+cmgoffena13@users.noreply.github.com> Date: Wed, 9 Sep 2026 18:38:16 -0600 Subject: [PATCH] fix(fabric): no-op warehouse create when the name already exists Signed-off-by: Cortland Goffena <30168413+cmgoffena13@users.noreply.github.com> --- sqlmesh/core/engine_adapter/fabric.py | 2 +- tests/core/engine_adapter/test_fabric.py | 43 ++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/sqlmesh/core/engine_adapter/fabric.py b/sqlmesh/core/engine_adapter/fabric.py index 7b2f1acd73..8a32bfa97e 100644 --- a/sqlmesh/core/engine_adapter/fabric.py +++ b/sqlmesh/core/engine_adapter/fabric.py @@ -361,7 +361,7 @@ def create_warehouse( if ( if_not_exists - and response.status_code == 400 + and response.status_code in (400, 409) and (errorCode := response.json().get("errorCode", None)) ): if errorCode == "ItemDisplayNameAlreadyInUse": diff --git a/tests/core/engine_adapter/test_fabric.py b/tests/core/engine_adapter/test_fabric.py index d16e973e8a..a6760e9531 100644 --- a/tests/core/engine_adapter/test_fabric.py +++ b/tests/core/engine_adapter/test_fabric.py @@ -4,10 +4,12 @@ import pandas as pd # noqa: TID253 import pytest +import requests from pytest_mock import MockerFixture from sqlglot import exp, parse_one from sqlmesh.core.engine_adapter import FabricEngineAdapter +from sqlmesh.core.engine_adapter.fabric import FabricHttpClient from tests.core.engine_adapter import to_sql_calls from sqlmesh.core.engine_adapter.shared import DataObject @@ -19,6 +21,26 @@ def adapter(make_mocked_engine_adapter: t.Callable) -> FabricEngineAdapter: return make_mocked_engine_adapter(FabricEngineAdapter) +@pytest.fixture +def fabric_http_client(mocker: MockerFixture) -> FabricHttpClient: + client = FabricHttpClient( + tenant_id="tenant-id", + workspace_id="workspace-id", + client_id="client-id", + client_secret="client-secret", + ) + client.session = mocker.MagicMock() + return client + + +def _conflict_response(mocker: MockerFixture, error_code: str) -> t.Any: + resp = mocker.MagicMock() + resp.status_code = 409 + resp.json.return_value = {"errorCode": error_code} + resp.raise_for_status.side_effect = requests.HTTPError(response=resp) + return resp + + def test_get_current_catalog_uses_only_explicit_target_catalog( make_mocked_engine_adapter: t.Callable, ): @@ -451,3 +473,24 @@ def test_comments(make_mocked_engine_adapter: t.Callable, mocker: MockerFixture) create_table_comment_mock.assert_not_called() create_column_comments_mock.assert_not_called() assert to_sql_calls(adapter) == [] + + +def test_create_warehouse_already_exists_is_noop( + fabric_http_client: FabricHttpClient, mocker: MockerFixture +) -> None: + fabric_http_client.session.post.return_value = _conflict_response( + mocker, "ItemDisplayNameAlreadyInUse" + ) + + fabric_http_client.create_warehouse("my_warehouse") + + fabric_http_client.session.post.assert_called_once() + + +def test_create_warehouse_unrelated_conflict_still_raises( + fabric_http_client: FabricHttpClient, mocker: MockerFixture +) -> None: + fabric_http_client.session.post.return_value = _conflict_response(mocker, "SomeOtherError") + + with pytest.raises(requests.HTTPError): + fabric_http_client.create_warehouse("my_warehouse")