---
title: "Creating Nodes with Attachments Programmatically · Appnovation"
url: "https://www.appnovation.com/insights/creating-nodes-attachments-programmatically"
description: "How to programmatically create Drupal nodes with file attachments, with a sample migration script you can adapt for your own content."
---

Article

# Creating Nodes with Attachments Programmatically

[![](https://cdn.sanity.io/images/ey850001/production/86e3d5924e4bfabe671e1dd9adeaf528d5ea749e-68x68.png?w=68&auto=format) dliau dliau Developer](/people/dliau-dliau.md) Mar 16, 2011  
 2 min read 

![Appnovation Blog Default Header](https://cdn.sanity.io/images/ey850001/production/9efe1c26d9584ecfb3dfef5a63e698bf4567d305-1440x600.jpg?w=1400&auto=format) 

There are many situations where programmatically creating a node is necessary. I'm sure we've all used this method at least once and each time may call for a slightly different configuration. Recently, I wrote a script to migrate a fairly small number of nodes (around 150). Along with the standard title, body, status and fields, I also had to migrate terms and attachments. Terms are fairly easy, but I've never needed to migrate attachments until now. I found a site which was very helpful with [programmatically including attachments (opens in new window)](http://workingdirectory.net/posts/2009/attach-file-to-node-drupal-6/) to a node. This is not to attach file to a file field, but to attach files as an attachment which uses the core Upload module. The main chunk of code is below:

foreach ($files as $file) {   $file\_obj = new stdClass();   $file\_obj->filename = $file->filename;   $file\_obj->filepath = $file->filepath;   $file\_obj->filemime = $file->filemime;   $file\_obj->filesize = $file->filesize;   $file\_obj->filesource = $file->filename;      // You can change this to the UID you want   $file\_obj->uid = $file->uid;   $file\_obj->status = $file->status;   $file\_obj->timestamp = $file->timestamp;   $file\_obj->list = 1;   $file\_obj->new = true;      // Save file to files table   drupal\_write\_record('files', $file\_obj);      // Attach the file object to your node   $node->files\[$file\_obj->fid\] = $file\_obj; } 

First thing we need to do is create a new file object. Fill in the file name, path, mime, size and source variables. In my case, I had these variables available from the old database, so I needed to save the new object into the new files table to get a file ID. These variables can also be retrieved by [file\_save\_upload (opens in new window)](http://api.drupal.org/api/drupal/includes--file.inc/function/file_save_upload/6) if you're uploading a new file. Afterwards, each file ID needs to be set as an array in the node object. Then node\_save to commit the changes. Saved attachments are written into the upload table where they can reference the file ID and node ID.

[![](https://cdn.sanity.io/images/ey850001/production/86e3d5924e4bfabe671e1dd9adeaf528d5ea749e-68x68.png?w=68&auto=format) dliau dliau Developer · Appnovation](/people/dliau-dliau.md) 

## Keep reading

[![What is Sovereign AI](https://cdn.sanity.io/images/ey850001/production/a5889abdd5e80376912546622e046e3fbef234b4-2496x1664.png?w=640&auto=format)](/insights/what-is-open-source-sovereign-ai.md)

 Article · 7 min AI 

### [What Is Open Source, Sovereign AI?](/insights/what-is-open-source-sovereign-ai.md)

Every company is encouraging more AI, and almost every AI bill is climbing. Sovereign AI is about two kinds of control: over your data and over your costs. Here's why open source sits at its foundation.

[Iain MacNeil](/people/iain-macneil.md) Article 

[![AI-first experience design](https://cdn.sanity.io/images/ey850001/production/8bbc2418e87924ef10f36115478a2e10d5bed95e-1584x624.jpg?w=640&auto=format)](/insights/how-build-ai-first-experience-without-throwing-out-everything-youve-already-built.md)

 Article · 6 min AI Sep 10, 2026 

### [How to Build an AI-First Experience Without Throwing Out Everything You've Already Built](/insights/how-build-ai-first-experience-without-throwing-out-everything-youve-already-built.md)

Users now expect a direct answer, not a list of links to click through. Here's how organizations can layer an AI-First experience onto their existing website or app, in weeks rather than years.

[Andrew Douglas](/people/andrew-douglas.md) Article 

[![What Becomes Possible When AI Can Read All the Data](https://cdn.sanity.io/images/ey850001/production/c28ab0bd26753421ee42937e13adc7a7f19b47f0-1296x510.jpg?w=640&auto=format)](/insights/what-becomes-possible-when-ai-can-read-all-data.md)

 Article · 4 min AI Sep 09, 2026 

### [What Becomes Possible When AI Can Read All the Data](/insights/what-becomes-possible-when-ai-can-read-all-data.md)

Most of the world's data has never been analyzed, only sampled. AI changes that. How AI-ready data platforms unlock questions no one could ask before.

[Appnovation](/people/appnovation.md) Article 

## Get the thinking,  
*before everyone else.*

One considered email a month. New essays, field notes from live engagements, and the occasional strong opinion. No noise.
