Evris Koukoumakas
10/16/2025, 6:22 PMversion: 1
default_environment: dev
project_id: 0199dcf7-566b-717d-bf2d-eaa09b89fa49
environments:
- name: dev
config:
plugins:
loaders:
- name: target-postgres
config:
database: postgres
host: localhost
user: postgres
plugins:
extractors:
- name: tap-facebook
variant: meltanolabs
pip_url: git+<https://github.com/MeltanoLabs/tap-facebook.git>
config:
start_date: 2025-01-01
select:
- campaigns.*
- adsets.*
- ads.*
- adsinsights_default.*
- videos.*
- images.*
- creatives.*
loaders:
- name: target-postgres
variant: meltanolabs
pip_url: meltanolabs-target-postgres
config:
add_record_metadata: true
jobs:
- name: meta-ads-to-postgres
tasks:
- tap-facebook target-postgres
schedules:
- name: business_1
interval: "@daily"
env:
TARGET_POSTGRES_DEFAULT_TARGET_SCHEMA: business_1_data
TAP_FACEBOOK_ACCOUNT_ID: "XXXX"
job: meta-ads-to-postgres
- name: business_2
interval: "@daily"
env:
TARGET_POSTGRES_DEFAULT_TARGET_SCHEMA: business_2_data
TAP_FACEBOOK_ACCOUNT_ID: "XXXX"
job: meta-ads-to-postgres
So basically I want to sync Facebook ad data from 2 separate businesses to 2 separate postgres schemas.
So after running sync for 1 business, I checked the state table in sqlite and saw this:
sqlite> select * from state;
prod:tap-facebook-to-target-postgres|{}|{"singer_state": {"bookmarks": {"adimages": {"replication_key": "updated_time", "replication_key_value": "2025-10-16T18:04:44.006000+00:00"}, "ads": {"replication_key": "updated_time", "replication_key_value": "2025-10-17T00:24:48+1100"}, "adsets": {"replication_key": "updated_time", "replication_key_value": "2025-10-16T09:56:49+1100"}, "adsinsights_default": {"replication_key": "date_start", "replication_key_value": "2025-10-17"}, "advideos": {"replication_key": "id", "replication_key_value": "999998314788384"}, "campaigns": {"replication_key": "updated_time", "replication_key_value": "2025-10-10T00:08:44+1100"}, "creatives": {"replication_key": "id", "replication_key_value": "998775395547354"}}}}|2025-10-16 18:10:15.088932
Basically I see that the state for incremental replication is stored on the extractor level. Since each schedule uses the same extractor but gets the data from a different ad account would't that break the incremental replication for the second sync?
Let me know if I am missing something and I would appreciate any feedback if this is not the best design pattern for the meltano config. Still a meltano newbie.
Thanks in advance!Andy Carter
10/17/2025, 8:10 AMtap-facebook you can give them different namespaces to avoid state collision
https://docs.meltano.com/concepts/plugins/#plugin-inheritanceAndy Carter
10/17/2025, 8:11 AMEvris Koukoumakas
10/17/2025, 12:05 PMversion: 1
default_environment: dev
project_id: 0199dcf7-566b-717d-bf2d-eaa09b89fa49
environments:
- name: dev
config:
plugins:
loaders:
- name: target-postgres
config:
database: postgres
host: localhost
user: postgres
plugins:
extractors:
- name: tap-facebook
variant: meltanolabs
pip_url: git+<https://github.com/MeltanoLabs/tap-facebook.git>
config:
start_date: 2025-01-01
select:
- campaigns.*
- adsets.*
- ads.*
- adsinsights_default.*
- videos.*
- images.*
- creatives.*
- name: business1_ extractor
inherit_from: tap-facebook
config:
account_id: "XXXX"
- name: business2_extractor
inherit_from: tap-facebook
config:
account_id: "XXXX"
loaders:
- name: target-postgres
variant: meltanolabs
pip_url: meltanolabs-target-postgres
config:
add_record_metadata: true
- name: business1_loader
inherit_from: target-postgres
config:
default_target_schema: business1_data
- name: business2_loader
inherit_from: target-postgres
config:
default_target_schema: business2_data
jobs:
- name: meta-ads-to-postgres-job
tasks:
- business1_extractor business1_loader
- business2_extractor business2_loader
schedules:
- name: meta-ads-to-postgres-schedule
interval: "@daily"
job: meta-ads-to-postgres-jobAndy Carter
10/17/2025, 2:28 PMEvris Koukoumakas
10/17/2025, 2:36 PMEvris Koukoumakas
10/17/2025, 2:37 PM