Extracting spreadsheet from blob column in MySQL database

Hi,

I have a MySQL table that contains spreadsheet files that are stored in a blob column - I’m struggling to see how I can extract this spreadsheet file from the relevant column and write it to a file.

Is this feasible?

Thanks
Scott

Hi @scottjscott,

In theory is it not just a select from the database then using the spreadsheet file node to write the data out maybe with a little function in the middle to do any changes.

Hey @scottjscott,

Welcome to the community :sparkling_heart:

It is possible, but you would have to make the blob readable by n8n. As @jon mentioned, you can use a Function node in your workflow to do the manipulation.

Thanks both for the advice so far. It’s the function to do the manipulation that is eluding me.

You can see the nodes in my workflow here which all run, but they produce a file that excel won’t open, clearly because I need to use a function to convert the data coming from the database blob into something that n8n can read.

I suspect my Set node needs to be replaced with a function, but I lack the javascript knowledge to write such a function.

Here is my workflow - I’m sure I’m making a bunch of noob mistakes!

{
  "name": "My workflow",
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=SELECT\n\tFile \nFROM\n\tVinylAudit.AuditUpload \nWHERE \n\tAuditUploadID = '5329baa7-0648-43dd-b05e-289f3072828a'"
      },
      "name": "MySQL",
      "type": "n8n-nodes-base.mySql",
      "typeVersion": 1,
      "position": [
        450,
        300
      ],
      "credentials": {
        "mySql": "QA - PCL Audit"
      }
    },
    {
      "parameters": {
        "fileName": "/tmp/spreadsheet3.xlsx",
        "dataPropertyName": "=binaryoutput"
      },
      "name": "Write Binary File1",
      "type": "n8n-nodes-base.writeBinaryFile",
      "typeVersion": 1,
      "position": [
        1050,
        300
      ]
    },
    {
      "parameters": {
        "mode": "jsonToBinary",
        "convertAllData": false,
        "sourceKey": "=binarydata",
        "destinationKey": "binaryoutput",
        "options": {
          "fileName": "spreadsheet1.xlsx",
          "mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        }
      },
      "name": "Move Binary Data2",
      "type": "n8n-nodes-base.moveBinaryData",
      "typeVersion": 1,
      "position": [
        850,
        300
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "binarydata",
              "value": "={{$node[\"MySQL\"].json[\"File\"][\"data\"].join(', ')}}"
            }
          ]
        },
        "options": {
          "dotNotation": false
        }
      },
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        650,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "MySQL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MySQL": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Binary File1": {
      "main": [
        []
      ]
    },
    "Move Binary Data2": {
      "main": [
        [
          {
            "node": "Write Binary File1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set": {
      "main": [
        [
          {
            "node": "Move Binary Data2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {},
  "id": "3"
}

Hey @scottjscott,

Unfortunately I don’t have a lot of experience with blobs and I don’t have dummy data to find out solutions. However, doing some quick search on the internet I found this: Blob.text() - Web APIs | MDN

Can you try this method?

When you query the blob field you have to use the TO_BASE64 function. Then, using the binary data base64 encoded you can create the binary structure in n8n using a function node.

SELECT `id`,`name`, TO_BASE64(content) FROM `db`.`upload`

The function node should be some similar to:

const results = []

for (const item of items) {
//Here you use the name of blob field.
//I used 'binaryfield' as an example.
  binaryData = items.json.binaryfield
  
  delete items.json.binaryfield
  
  results.push({
    json: {
      ...item.json,
    },
    binary: {
      data: {
        data: binaryData,
        mimeType: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ,
        fileExtension: 'xlsx',
      }
    }
  })
}

return results;
3 Likes

Thanks for the pointers @RicardoE105 - I will do a bit of RTFM on the javascript function :sweat_smile:

Quick update, I’ve managed to get things working without a function with the following nodes:

  1. MySQL node:
    The key guidance here was using the TO_BASE64(content) in the SQL statement, but also by adding TO_BASE64(content) as binaryfield as follows so that the variable is available to other nodes:
SELECT TO_BASE64(content) as binaryfield FROM TABLE
  1. Move Binary Data node
    This node moves the data from JSON to Binary, but only works if I enable the Data is Base64 from the options as circled below:

Then it was just a simple case of writing binary file with the final node.

The final workflow is below - I’ll have to fumble my way through a javascript function at some point in the future! Thanks to everybody for their help.

{
  "name": "get binary file from blob column",
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "operation": "executeQuery",
        "query": "=SELECT\n\tTO_BASE64(File) as binaryfield\nFROM\n\tVinylAudit.AuditUpload \nWHERE \n\tAuditUploadID = '5329baa7-0648-43dd-b05e-289f3072828a'"
      },
      "name": "MySQL",
      "type": "n8n-nodes-base.mySql",
      "typeVersion": 1,
      "position": [
        450,
        300
      ],
      "credentials": {
        "mySql": "QA - PCL Audit"
      }
    },
    {
      "parameters": {
        "fileName": "/tmp/spreadsheet3.xlsx",
        "dataPropertyName": "=binaryoutput"
      },
      "name": "Write Binary File1",
      "type": "n8n-nodes-base.writeBinaryFile",
      "typeVersion": 1,
      "position": [
        860,
        300
      ]
    },
    {
      "parameters": {
        "mode": "jsonToBinary",
        "convertAllData": false,
        "sourceKey": "=binaryfield",
        "destinationKey": "binaryoutput",
        "options": {
          "dataIsBase64": true,
          "fileName": "spreadsheet1.xlsx",
          "mimeType": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
        }
      },
      "name": "Move Binary Data",
      "type": "n8n-nodes-base.moveBinaryData",
      "typeVersion": 1,
      "position": [
        650,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "MySQL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "MySQL": {
      "main": [
        [
          {
            "node": "Move Binary Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Move Binary Data": {
      "main": [
        [
          {
            "node": "Write Binary File1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Binary File1": {
      "main": [
        []
      ]
    }
  },
  "active": false,
  "settings": {},
  "id": "3"
}

2 Likes

Ahh, good to know. Actually, I learn that you could do this 1 hour ago from @jan. I had no clue about that. This is one of the many things I like about n8n. I have been working with it for over a year and keep discovering new things.

@scottjscott have fun, and thanks for sharing the solution with the community.

1 Like