I am in the process of importing large amounts of data into a custom post type that has several custom fields (postmeta fields created by Advanced Custom Fields). I am using the following function to import the data and it works fine with my test file of about 10 posts with the exception of the postmeta. Here is the function I am using for the import:

function mysite_import_json() {
  $json_feed = 'http://local.mysite.com/wp-content/test.json';
  $json      = file_get_contents( $json_feed );
  $objs      = json_decode( $json, true );
  $wp_error  = true;
  $post_id   = - 1;

foreach ( $objs as $obj ) {
    $title   = $obj['title'];
    $meta1  = $obj['taxonomy'][0];
    $meta2     = $obj['nom'];
    $meta3  = $obj['prenom'];
    $d       = new DateTime();
    $d->setTimestamp( $obj['created'] );
    $date_created = $d->format( 'Y-m-d H:i:s' );
    $post_meta    = array(
        'meta_1'        => $meta1,
        'meta_2'        => $meta2,
        'meta_3'        => $meta3,

    $post_data = array(
        'post_title'  => $title,
        'post_date'   => $date_created,
        'post_status' => 'publish',
        'post_type'   => 'cpt',
        'meta_input'  => $post_meta,

    if ( null === get_page_by_title( $title, 'object', 'message' ) ) {
        $post_id = wp_insert_post( $post_data, $wp_error );
        foreach ( $post_meta as $key => $value ) {
               update_field( $key, $value, $post_id );
    } else {
        $post_id = - 2;

add_action( 'after_setup_theme', 'mysite_import_json' );

The post meta is indeed imported but I have to manually click the update button in order to display the data on the front-end. I researched this a bit and found this (below, I would link the article but I've lost it) which I tried and limited the number of posts to 10 to rule out memory problems but it still doesn't have the desired effect of reproducing the click on publish button.

function mass_update_posts() {

   $args = array(
       'post_type'      => 'message',
       'posts_per_page' => 10

$my_posts = get_posts( $args );

foreach ( $my_posts as $key => $my_post ) {
    $meta_values = get_post_meta( $my_post->ID );
    foreach ( $meta_values as $meta_key => $meta_value ) {
        update_field( $meta_key, $meta_value[0], $my_post->ID );

add_action( 'init', 'mass_update_posts' );

I am also aware that this is going to be expensive memory-wise and am not sure the best way to go about this. Maybe in batches?

EDIT: I should mention that the data is displayed on the front end by way of the WP API which actually seems to be the issue. So I suppose I need to update the API rather that the post meta in the database. The plugin that displays the ACF meta data for the WP API is ACF to WP-API.

2 Answers 2


update_field() is ACF function so I would guess the issue is with it. From quick look at source it calls get_field_object() and so on, so environment might not be sufficient for it to work correctly during import.

There is no "half" state for native meta data, either it exists in database or it doesn't. You could try to stick with native WP API for meta data, but no idea what is actually required for ACF to pick it up properly.

  • I also tried update_post_meta( $post_id, $key, $value ) and couldn't get it to work with that either. I definitely exists in the database and the issue might be that it is not published to the WP API which is actually the mechanism by which the data is displayed.
    – mantis
    Commented May 14, 2016 at 10:51

Just adding this for posterity in case anyone else comes across this. The issue is indeed with ACF which adds inserts two rows into the the database.

meta_key       | meta_value
 {$field_name} | $value
_{$field_name} | $field_key

So in order to import postmeta into ACF fields you also need to add the second row of postmeta containing the field name (preceded by an underscore) and the field key which looks something like field_16d7f66185fc6

So in the previous example there needs to be a second array like so:

$field_meta    = array(
        '_meta_1'        => field_16d6e32f46959,
        '_meta_2'        => field_16d6e42d461ce,
        '_meta_3'        => field_16d6e5254695c,

Which is looped through after the wp_insert_post() function:

$post_id = wp_insert_post( $post_data, $wp_error );

foreach ( $field_meta as $key => $value ) {
    update_post_meta( $post_id, $key, $value );

Once the second row of field meta is added the fields are available in the WP-API.

  • As of 08/2020 .. using update_field( $key, $val, $post_id ) seems to work as expected, note that $val must be in the exact format as expected per the ACF field type used .. for more details see advancedcustomfields.com/resources/update_field
    – farinspace
    Commented Aug 12, 2020 at 23:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.