contentful-cli icon indicating copy to clipboard operation
contentful-cli copied to clipboard

Missing support for 'include' parameter in query to include linked entries?

Open Sammii opened this issue 5 years ago • 7 comments

Context

Since the documentation states:

All search parameters of our API are supported as documented in our API documentation.

I would expect that, as documented here, I am able to use the include param in my query in order to export linked items using the CLI. Currently, I can't find any way to export linked entries using the CLI without explicitly declaring every entry ID.

Expected Behavior

"include=10" as a query in queryEntries should include linked entries in the export.

Actual Behavior

Linked entries are not exported. Example: "queryEntries": ["content_type=page", "include=10", "sys.id=1XCqR7ojOoxjQpbeAAfSWW"], only exports a single entry.

Sammii avatar Oct 07 '20 22:10 Sammii

Could you explain the use case a bit?
I assume you want to do something like exporting a single entry together with all related entities that you then have as a single export file that preserves the full entry context.

Would you then import that partial export into a separate space or is it kept as a backup to be imported into the same space? Since it fetches all related entries at that point I could imagine that being trouble when reimporting since it might be unexpected that the related entities that might be reused elsewhere get overwritten.

TimBeyer avatar Nov 16 '20 16:11 TimBeyer

Could you explain the use case a bit?

Migrating content from one environment to another environment. We often publish content in a staging environment that is not customer-facing before migrating it to master where it becomes live on our production site.

I assume you want to do something like exporting a single entry together with all related entities that you then have as a single export file that preserves the full entry context.

Yes. Having to manually specify every single linked entry id for export is very onerous and error prone. If we miss one, then the parent page could not be published.

Would you then import that partial export into a separate space or is it kept as a backup to be imported into the same space?

Into a separate environment, not a space. We use the export to copy changes (content types and entries) between environments.

Sammii avatar Nov 17 '20 17:11 Sammii

@TimBeyer Just wanted to check in on this issue as it has been several months - any updates?

Sammii avatar Apr 07 '21 19:04 Sammii

Hi @Sammii running into the same use case, what was your strategy in the end?

diegoaguilar avatar Aug 16 '21 11:08 diegoaguilar

Hi @Sammii running into the same use case, what was your strategy in the end?

Hi @diegoaguilar, since I never got any resolution via the official CLI, I built my own Node script instead to achieve this behaviour, relying on the new "References" endpoint. 🥲 It makes a fetch to: https://api.contentful.com/spaces/${argv.spaceId}/environments/${argv.environmentId}/entries/${id}/references?access_token=${managementToken}&include=10

Here's a link to the docs for the endpoint: https://www.contentful.com/developers/docs/references/content-management-api/#/reference/entries/entry-references

Sammii avatar Aug 16 '21 23:08 Sammii

Ohh I get it. I wasn't that aware of this dedicated endpoint. I think that might be what getDerivedEntries uses.

This might be helpful for me. Thanks!

On Mon, Aug 16, 2021 at 6:42 PM Samantha @.***> wrote:

Hi @Sammii https://github.com/Sammii running into the same use case, what was your strategy in the end?

Hi @diegoaguilar https://github.com/diegoaguilar, since I never got any resolution via the official CLI, I built my own Node script instead to achieve this behaviour, relying on the new "References" endpoint. 🥲 It makes a fetch to: https://api.contentful.com/spaces/${argv.spaceId}/environments/${argv.environmentId}/entries/${id}/references?access_token=${managementToken}&include=10

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/contentful/contentful-cli/issues/614#issuecomment-899887472, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAS6LXWAPNRL5ZWW56Y2AE3T5GO4ZANCNFSM4SH7LJCQ .

diegoaguilar avatar Aug 17 '21 12:08 diegoaguilar

A Complete solution to Export/Import Entry with it's children from environment to another one

const contentful = require('contentful-management')
const contentfulExport = require('contentful-export')
const contentfulImport = require('contentful-import')

const SPACE_ID = '<space_id>'
const MANAGEMENT_TOKEN = '<management_token>'
const SOURCE_ENV_ID = '<source_environment_id>'
const TARGET_ENV_ID = '<target_environment_id>'
const ENRTY_ID = '<entry_id_to_export>'
const CONTENT_FILE_URL = '<target_json_file_to_save_data_to>'
const maxDepth = '<maximum_depth>'

const options = {
  spaceId: SPACE_ID,
  environmentId: SOURCE_ENV_ID,
  managementToken: MANAGEMENT_TOKEN,
  contentFile: CONTENT_FILE_URL,
  contentOnly: false,
  downloadAssets: false,
  skipContent: false,
  skipRoles: true,
  skipWebhooks: true,
}

const client = contentful.createClient({
  accessToken: options.managementToken,
})

const exportEntries = async (options) => {
  return await contentfulExport(options)
    .then((result) => {
      const importOptions = {
        contentFile: CONTENT_FILE_URL,
        spaceId: SPACE_ID,
        managementToken: MANAGEMENT_TOKEN,
        environmentId: TARGET_ENV_ID,
      }

      contentfulImport(importOptions).catch((err) => {
        console.log('Oh no! Some errors occurred!', err)
      })
    })
    .catch((err) => {
      console.log('Oh no! Some errors occurred!', err)
    })
}

// Get entry references
client
  .getSpace(options.spaceId)
  .then((space) => space.getEnvironment('staging'))
  .then((environment) => environment.getEntryReferences(ENRTY_ID, { maxDepth })) // Get Entry References Contents and assets
  .then((entry) => {
    const entries = entry.includes?.Entry.map((e) => e.sys.id).join(',') || ''
    const assets = entry.includes?.Asset.map((e) => e.sys.id).join(',') || ''

    options.queryEntries = [`sys.id[in]=${ENRTY_ID},${entries}`]
    options.queryAssets = [`sys.id[in]=${assets}`]

    exportEntries(options)
  })
  .catch(console.error)

hanivic505 avatar Oct 31 '21 21:10 hanivic505

@hanivic505 Hey how you run this script to export and import specific entry.

asharani009 avatar Oct 19 '22 16:10 asharani009

closing the issue, if you still need help with this please reach out to Contentful support

mayakarabula avatar Jun 13 '23 14:06 mayakarabula

A Complete solution to Export/Import Entry with it's children from environment to another one

Thanks for providing this script @hanivic505 - super helpful.

abouthalf avatar Feb 17 '24 17:02 abouthalf