Forum Discussion
SQL Endpoint lakehouse: Intermittent error in the Refresh SQL analytics endpoint activity
- 26 days ago
Thank you for all the responses, going down the full api/notebook route is too much of an overhead for us at the moment. It would require us to set up a service principal, api keys etc, which we (don't) have (yet) (very small team :-) )
We do know from experience that a 5-minute wait in our pipeline, though ugly, solved the issue. Endpoints would have synched by then.
(The only time that did not work flawless was on 1 pipeline that ran at 130 am in the morning, when the lakehouse was well deep asleep. I solved that by running a dummy script against the endpoint...select top (1) from etc etc.
With that in mind I would think that (in our situation) "on completion" would be safe?
CheersHans
Hi smeetsh,
On your continue-on-failure idea, one option that gives you a deterministic answer instead of guessing is to call the refresh API directly rather than through the pipeline activity, because the API returns a status per table.
POST https://api.fabric.microsoft.com/v1/workspaces/{workspaceId}
/sqlEndpoints/{sqlEndpointId}/refreshMetadataTwo optional body parameters in the Refresh SQL Endpoint Metadata API help with your exact situation:
tables -> refresh only the tables this pipeline wrote
(up to 25 per call)
timeout -> defaults to 15 minutes, can be raisedThe response lists each table with a status (Success, Failure or NotRun) and its lastSuccessfulSyncDateTime.
A minimal notebook version, which you can call from the pipeline in place of the activity:
import time, requests
ws_id, ep_id = "<workspaceId>", "<sqlEndpointId>"
token = notebookutils.credentials.getToken("pbi")
h = {"Authorization": f"Bearer {token}"}
url = (f"https://api.fabric.microsoft.com/v1/workspaces/{ws_id}"
f"/sqlEndpoints/{ep_id}/refreshMetadata")
body = {
"tables": [{"schema": "dbo",
"tableNames": ["trev_checklist_data"]}],
"timeout": {"timeUnit": "Minutes", "value": 30},
}
r = requests.post(url, headers=h, json=body)
if r.status_code == 202: # long-running operation
op_url = r.headers["Location"]
while True:
time.sleep(int(r.headers.get("Retry-After", 15)))
r = requests.get(op_url, headers=h)
if r.json().get("status") in ("Succeeded", "Failed"):
break
r = requests.get(op_url + "/result", headers=h)
statuses = r.json()["value"]
failed = [t["tableName"] for t in statuses
if t["status"] != "Success"]
notebookutils.notebook.exit(
"OK" if not failed else "FAILED:" + ",".join(failed))Then in the pipeline:
Notebook (scoped refresh)
-> If Condition on the exit value
-> OK : continue to Copy data
-> FAILED : Fail activity with the table namesThat gives you the "continue anyway" behavior you described, but only when the tables you actually depend on have synced, rather than assuming they did because the activity ran for 12 minutes.
Scoping each call to a few tables also means a pipeline is no longer asking for a full endpoint sync while other pipelines are still writing to the Lakehouse, which should reduce the lock contention behind these timeouts.
So my overall approach would be:
scoped refresh per pipeline
-> per-table status check
-> continue only when the tables you need are synced
-> short retry with delay for genuine transient errorsThat keeps your pipelines independent without giving up the guarantee that downstream steps read current data.
AI-assisted drafting: AI was used to help structure and phrase this response. I reviewed and validated the technical content before posting.