diff --git a/enterprise/backend/test/metabase_enterprise/serialization/v2/extract_test.clj b/enterprise/backend/test/metabase_enterprise/serialization/v2/extract_test.clj index 87ab352519cce4116b4a0a83ac71bcbc2134c04b..fbb8c471e22954b2650a63f8accbe8dd670a9f85 100644 --- a/enterprise/backend/test/metabase_enterprise/serialization/v2/extract_test.clj +++ b/enterprise/backend/test/metabase_enterprise/serialization/v2/extract_test.clj @@ -1031,3 +1031,22 @@ (->> (extract/extract-subtrees {:targets [["Collection" coll1-id]]}) (map serdes.base/serdes-path) set))))))))) + +(deftest foreign-key-field-test + (ts/with-empty-h2-app-db + (ts/with-temp-dpc [Database [{db-id :id} {:name "My Database"}] + Table [{no-schema-id :id} {:name "Schemaless Table" :db_id db-id}] + Field [{some-field-id :id} {:name "Some Field" :table_id no-schema-id}] + Table [{schema-id :id} {:name "Schema'd Table" + :db_id db-id + :schema "PUBLIC"}] + Field [_ {:name "Other Field" :table_id schema-id}] + Field [{fk-id :id} {:name "Foreign Key" + :table_id schema-id + :fk_target_field_id some-field-id}]] + + (testing "fields that reference foreign keys are properly exported as Field references" + (is (= ["My Database" nil "Schemaless Table" "Some Field"] + (->> (db/select-one Field :id fk-id) + (serdes.base/extract-one "Field" {}) + :fk_target_field_id))))))) diff --git a/enterprise/backend/test/metabase_enterprise/serialization/v2/load_test.clj b/enterprise/backend/test/metabase_enterprise/serialization/v2/load_test.clj index ec0153ad3ad4005553311d341270956502e706df..78453c2135638d2dd7de7fd6a684d388486f0422 100644 --- a/enterprise/backend/test/metabase_enterprise/serialization/v2/load_test.clj +++ b/enterprise/backend/test/metabase_enterprise/serialization/v2/load_test.clj @@ -116,7 +116,9 @@ db2s (atom nil) db2d (atom nil) t1s (atom nil) - t2s (atom nil)] + t2s (atom nil) + f1s (atom nil) + f2s (atom nil)] (ts/with-source-and-dest-dbs (testing "serializing the two databases" (ts/with-source-db @@ -124,6 +126,8 @@ (reset! t1s (ts/create! Table :name "posts" :db_id (:id @db1s))) (reset! db2s (ts/create! Database :name "db2")) (reset! t2s (ts/create! Table :name "posts" :db_id (:id @db2s))) ; Deliberately the same name! + (reset! f1s (ts/create! Field :name "Target Field" :table_id (:id @t1s))) + (reset! f2s (ts/create! Field :name "Foreign Key" :table_id (:id @t2s) :fk_target_field_id (:id @f1s))) (reset! serialized (into [] (serdes.extract/extract-metabase {}))))) (testing "serialization of databases is based on the :name" @@ -137,6 +141,14 @@ (map :db_id) set)))) + (testing "foreign key references are serialized as a field path" + (is (= ["db1" nil "posts" "Target Field"] + (->> @serialized + (filter #(-> % :serdes/meta last :model (= "Field"))) + (filter #(-> % :table_id (= ["db2" nil "posts"]))) + (keep :fk_target_field_id) + first)))) + (testing "deserialization works properly, keeping the same-named tables apart" (ts/with-dest-db (serdes.load/load-metabase (ingestion-in-memory @serialized)) diff --git a/src/metabase/models/field.clj b/src/metabase/models/field.clj index 4b7c95e4e21b7bf0bd719ee63f3626a8df205ece..af355e5c8dd80e305e7696846f6869bf4c22024f 100644 --- a/src/metabase/models/field.clj +++ b/src/metabase/models/field.clj @@ -407,12 +407,14 @@ (defmethod serdes.base/extract-one "Field" [_model-name _opts field] (-> (serdes.base/extract-one-basics "Field" field) - (update :table_id serdes.util/export-table-fk))) + (update :table_id serdes.util/export-table-fk) + (update :fk_target_field_id serdes.util/export-field-fk))) (defmethod serdes.base/load-xform "Field" [field] (-> (serdes.base/load-xform-basics field) - (update :table_id serdes.util/import-table-fk))) + (update :table_id serdes.util/import-table-fk) + (update :fk_target_field_id serdes.util/import-field-fk))) (defmethod serdes.base/load-find-local "Field" [path]