 
 ;; Each field-syncing function below should return FIELD with any updates that we made, or nil.
 ;; That way the next fn in the 'pipeline' won't trample over changes made by the last.
+
+;; ### set-field-display-name-if-needed!
+
+(defn set-field-display-name-if-needed!
+  "If FIELD doesn't yet have a `display_name`, calculate one now and set it."
+  [field]
+  (when (nil? (:display_name field))
+    (let [display-name (common/name->human-readable-name (:name field))]
+      (log/info (format "Field '%s.%s' has no display_name. Setting it now." (:name @(:table field)) (:name field) display-name))
+      (upd Field (:id field) :display_name display-name)
+      (assoc field :display_name display-name))))
+
 
 ;; ### mark-url-field!
 

         field]}
  (log/debug (format "Syncing field '%s.%s'..." (:name @(:table field)) (:name field)))
  (sync-field->> field
                 (mark-url-field! driver)
                 mark-category-field!
                 (mark-no-preview-display-field! driver)

   (e.g., `sync-table-fks!` can't run until all tables have finished `sync-table-active-fields-and-pks!`, since creating `ForeignKeys` to `Fields` of *other*
   Tables can't take place before they exist."
  [driver active-tables]

  ;; make sure table has :display_name
  (log/debug (color/green "Checking table display names..."))
  (doseq [table active-tables]
    (u/try-apply update-table-display-name! table))

  ;; update the row counts for every Table. These *can* happen asynchronously, but since they make a lot of DB calls each so
  ;; going to block while they run for the time being. (TODO - fix this)
  (log/debug (color/green "Updating table row counts..."))
