19

I would like to know How can I insert an image "bytea" into a table of my postgreSql database? I've been searching forums for hours and have seen the same question posted dozens of times, but yet to find a single answer. All I see is how to insert .jpeg's into an old column which isn't what I need.

Here's the database table:

create table category  (
"id_category" SERIAL,
"category_name" TEXT,
"category_image" bytea,
constraint id_cat_pkey primary key ("id_category"))without oids;

and when I add a new line, it doesn't work :

insert into category(category_name,category_image) values('tablette', lo_import('D:\image.jpg'));
8
  • Use a programming language to extract the file contents, or if you can't and you're superuser and the file is on the server, see How to insert (file) data into a PostgreSQL bytea column on dba.se Commented Mar 9, 2014 at 23:24
  • 1
    It is usually a better idea to save the image as a file on disk and just store a reference to it in the database. Commented Mar 9, 2014 at 23:56
  • 1
    Which programming language and client driver are you using? Also, lo_import isn't for bytea fields, it's for large objects (lob, pg_largeobject), per the documentation. Commented Mar 10, 2014 at 0:06
  • @Björn Nilsson: how can i save the image as o file on disk and how can i store the reference in my database? Commented Mar 10, 2014 at 8:20
  • I used the tool pgAdmin III to create and populate my postgreSql database Commented Mar 10, 2014 at 8:23

9 Answers 9

9

When the column type is bytea then you could use pg_read_binary_file().

Example: pg_read_binary_file('/path-to-image/')

See the documentation of pg_read_binary_file.

Sign up to request clarification or add additional context in comments.

Comments

4

None of the above example worked well for me and on top of that I needed to add many images at once.

Full working example (python 3) with explanations:

With get_binary_array we get the value of the image (or file) as a binary array, using its path and file name as parameter (ex: '/home/Pictures/blue.png').

With send_files_to_postgresql we send all the images at once.

I previously created the database with one sequential 'id' that will automatically be incremented (but you can use your own homemade id) and one bytea 'image' field

import psycopg2

def get_binary_array(path):
    with open(path, "rb") as image:
        f = image.read()
        b = bytes(f).hex()
        return b

def send_files_to_postgresql(connection, cursor, file_names):
    query = "INSERT INTO table(image) VALUES (decode(%s, 'hex'))"
    mylist = []
    for file_name in file_names:
        mylist.append(get_binary_array(file_name))

    try:
        cursor.executemany(query, mylist)
       
        connection.commit()  # commit the changes to the database is advised for big files, see documentation
        count = cursor.rowcount # check that the images were all successfully added
        print (count, "Records inserted successfully into table")
    except (Exception, psycopg2.DatabaseError) as error:
        print(error)

def get_connection_cursor_tuple():
    connection = None
    try:
        params = config()
        print('Connecting to the PostgreSQL database...')
        connection = psycopg2.connect(**params)
        cursor = connection.cursor()
    except (Exception, psycopg2.DatabaseError) as error:
        print(error)

    return connection, cursor

connection, cursor = connect_db.get_connection_cursor_tuple()
img_names = ['./blue.png', './landscape.jpg']
send_files_to_postgresql(connection, cursor, img_names)

Comments

3
insert into category(category_name,category_image) values('tablette', bytea('D:\image.jpg'));

The above solution works if column type is bytea

insert into category(category_name,category_image) values('tablette', lo_import('D:\image.jpg'));

The above solution works if column type is oid i.e., Blob

insert into category(category_name,category_image) values('tablette',decode('HexStringOfImage',hex));

The above decode function take two parameters. First parameter is HexString of Image.The second parameter is hex by default.Decode function coverts the hexString to bytes and store in bytea datatype column in postgres.

6 Comments

bytea('D:\image.jpg') will not read the image from the file specified. It simply converts the string constant 'D:\image.jpg' to its binary representation.
insert into category(category_name,category_image) values('tablette', 'R0lGODlhmgDAAIcAAAgICAGAAY8ZGQAAgIqCFYKEhxRGEkVKF73D');
Convert the given image to base64 encode string and paste there. I just given an simple example above. However it worked for me if column data type is oid.
Is there a way I can insert a file by giving the path and not 'D:\image.jpg' as binary ?
We can also use insert into category(category_name,category_image) values('tablette',decode('base 64 image string','base64'));
|
1
create table images (imgname text, img bytea);


insert into images(imgname,img) values ('MANGO', pg_read_binary_file('path_of_image')::bytea);

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
0

Something like this function (slightly adapted from here) could work out.

create or replace function img_import(filename text)
  returns void
  volatile
  as $$
    declare
        content_ bytea;
        loid oid;
        lfd integer;
        lsize integer;
    begin
        loid := lo_import(filename);
        lfd := lo_open(loid,131072);
        lsize := lo_lseek(lfd,0,2);
        perform lo_lseek(lfd,0,0);
        content_ := loread(lfd,lsize);
        perform lo_close(lfd);
        perform lo_unlink(loid);

    insert into category values
    ('tablette',
    content_);
    end;
$$ language plpgsql

Use it like select * from img_import('D:\image.jpg'); or rewrite to procedure if feeling like it.

Comments

0

create below function:

create or replace function bytea_import(p_path text, p_result out bytea) 
                       language plpgsql as $$
    declare
      l_oid oid;
    begin
      select lo_import(p_path) into l_oid;
      select lo_get(l_oid) INTO p_result;
      perform lo_unlink(l_oid);
    end;$$;

and use like this:

insert into table values(bytea_import('C:\1.png'));

Comments

0

For Linux users this is how to add the path to the image

insert into blog(img) values(bytea('/home/samkb420/Pictures/Sam Pics/sam.png'));

Comments

0

We can also use insert into category(category_name,category_image) values('tablette',decode('base 64 image string','base64')); – Navap May 29, 2020 at 2:03

This worked for me. Thanks My observations - the image should be in folder and the folder name should not have hyphen '-'. Also you should not mention extension of the image file like .jpg or .jpeg

1 Comment

For me, your answer is not clear. How is Navap May 29, 2020 at 2:03 related? I also think that you could improve the format of your answer with markdown.
-4

Use SQL workbench - Database explorer - insert a row and follow the dialogue...

enter image description here

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.