Skip to content

Conversation

@cnolanminich
Copy link
Contributor

Summary & Motivation

Resolves #32458

How I Tested These Changes

added tests, pytest, and BK

Changelog

Added a resync_and_poll method to FivetranWorkspace

@maximearmstrong maximearmstrong self-requested a review November 5, 2025 22:44
@cnolanminich cnolanminich marked this pull request as ready for review November 14, 2025 19:52
@cnolanminich cnolanminich requested a review from a team as a code owner November 14, 2025 19:52
context: dg.AssetExecutionContext, fivetran: FivetranWorkspace
):
# Perform a full historical resync of all tables in the connector
yield from fivetran.resync_and_poll(context=context)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh this is super helpful.

I wonder if in the example we should supply a config object and then conditionally call resync_and_poll if someone provides a resync=True flag, that way we can have one set of assets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I think that makes sense -- I was following the pattern from our old Fivetran resource but it's fair to say perhaps you want to alter the yield depending on config.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@cmpadden respun with config on sync_and_poll

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like where this landed, originally I was thinking you'd have the user define the config and have something like:

if config.resync:
    yield from fivetran.resync_and_poll(context=context)
else:
    yield from fivetran.sync_and_poll(context=context)

But defining the configuration for them is much cleaner and "batteries included".

@github-actions
Copy link

github-actions bot commented Nov 14, 2025

Deploy preview for dagster-docs ready!

Preview available at https://dagster-docs-7oe30bmak-elementl.vercel.app
https://christian-fivetran-resync-and-poll.archive.dagster-docs.io

Direct link to changed pages:

Comment on lines 475 to 492
# Mocked FivetranClient.resync_and_poll returns None if the connector is paused
result = materialize(
[my_fivetran_assets],
resources={"fivetran": workspace},
)
assert result.success
asset_materializations = [
event
for event in result.events_for_node(connector_id)
if event.event_type_value == "ASSET_MATERIALIZATION"
]
assert len(asset_materializations) == 0

captured = capsys.readouterr()
assert re.search(
r"dagster - WARNING - (?s:.)+ - The connector with ID (?s:.)+ has not been resynced.",
captured.err,
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test logic error: This test case does not pass resync=True in the run_config, so it will call _sync_and_poll() which invokes client.sync_and_poll(), not client.resync_and_poll(). However, the resync_and_poll fixture only mocks FivetranClient.resync_and_poll(). This means:

  1. The mocked return value of None (for paused connector) will never be returned
  2. The test will actually call the real sync_and_poll method (or fail if no mock exists for it)
  3. The assertion checking for the "has not been resynced" warning message will fail

Fix:

result = materialize(
    [my_fivetran_assets],
    resources={"fivetran": workspace},
    run_config={"ops": {connector_id: {"config": {"resync": True}}}},
)
Suggested change
# Mocked FivetranClient.resync_and_poll returns None if the connector is paused
result = materialize(
[my_fivetran_assets],
resources={"fivetran": workspace},
)
assert result.success
asset_materializations = [
event
for event in result.events_for_node(connector_id)
if event.event_type_value == "ASSET_MATERIALIZATION"
]
assert len(asset_materializations) == 0
captured = capsys.readouterr()
assert re.search(
r"dagster - WARNING - (?s:.)+ - The connector with ID (?s:.)+ has not been resynced.",
captured.err,
)
# Mocked FivetranClient.resync_and_poll returns None if the connector is paused
result = materialize(
[my_fivetran_assets],
resources={"fivetran": workspace},
run_config={"ops": {connector_id: {"config": {"resync": True}}}},
)
assert result.success
asset_materializations = [
event
for event in result.events_for_node(connector_id)
if event.event_type_value == "ASSET_MATERIALIZATION"
]
assert len(asset_materializations) == 0
captured = capsys.readouterr()
assert re.search(
r"dagster - WARNING - (?s:.)+ - The connector with ID (?s:.)+ has not been resynced.",
captured.err,
)

Spotted by Graphite Agent

Fix in Graphite


Is this helpful? React 👍 or 👎 to let us know.

Copy link
Contributor

@cmpadden cmpadden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pending a green docs / docs_snippets build, I say we go ahead and merge this.

The oss-internal-compatibility error is unrelated.

[2025-11-14T21:49:16Z] src/connections/ConnectionStatus.tsx:1:19 - error TS2305: Module '"@dagster-io/ui-components"' has no exported member 'Intent'.
[2025-11-14T21:49:16Z]
[2025-11-14T21:49:16Z] 1 import {IconName, Intent} from '@dagster-io/ui-components';

@cnolanminich cnolanminich merged commit 10ebdb5 into master Nov 14, 2025
7 of 8 checks passed
@cnolanminich cnolanminich deleted the christian/fivetran-resync-and-poll branch November 14, 2025 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants