Saving Buffer on Postgres bytea with TypeORM only store 10 bytes

Posted on

Saving Buffer on Postgres bytea with TypeORM only store 10 bytes

I’m trying to save some images on a postgres db, but only 10 bytes of data are being saved.

The flow is something like this:

I receive a base64 encoded string on my server, then i load that to a Buffer, set it to my entity and save it.
But then a try to restore that information from db and i’m getting only 10 bytes of data, verified with octet_length() on a query.

My entity attribute definition:

@Column({ "name": "entima_imagem", "type": "bytea", "nullable": false })
entima_imagem: Buffer;

The code where i receive the data and save it:

entity.entima_imagem = Buffer.from(base64String, "base64");
const repository = this.getRepositoryTarget(Entity);
const saved = await repository.save<any>(entity);

On the server, before saving, i’m writing the file on disc and i can visualize it without problem.

Solution :

Based on that comment https://github.com/typeorm/typeorm/issues/2878#issuecomment-432725569 and the idea of bytea hex format from there https://www.postgresql.org/docs/9.0/datatype-binary.html I did the following:

Decoded the Buffer to a hex string, escaped it with x and then loaded it to a Buffer again.

entity.entima_imagem = Buffer.from("\x" + Buffer.from(base64String, "base64").toString("hex"));

Now the data is saved without problems and i can retrieve them just as it’s supposed to be.

It didn’t look so elegant, but solved the problem for now.

I had similar issue. It looks like typeorm has problems with 0x00 byte. It slices everything starting from first 0 byte.

A similar workaround worked for me:

@Column({ type: "bytea", nullable: false })
public file: Buffer;

while saving:

log.file = ("\x" + file.toString( "hex" )) as any;

Creating a buffer from “\x”+content string as @JDuwe suggested didn’t work for me.
I had to provide a string to typeorm, not Buffer.

Maybe since the last answer postgres or typeorm solved it, but on the latest version of both i managed to make this work without any “hack”
here is the code for entity column

@Column({
    name: 'imageData',
    type: 'bytea',
    nullable: false,
})
imageData: Buffer;

and only thing i did that converted base64 string to Buffer, but this is unrelated to typeorm

 constructor(imageDataBase64: string) {
    if (imageDataBase64) {
        this.imageData = Buffer.from(imageDataBase64, 'base64');
    }
}

Even I use sync feature of typeorm

During retrival:

imageData.toString('base64')

and i got back the original base64 string which can be inserted into webpage as image

Leave a Reply

Your email address will not be published. Required fields are marked *