Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [SOLVED]How send binary file to Postgres server?
Forum Updated to NodeBB v4.3 + New Features

[SOLVED]How send binary file to Postgres server?

Scheduled Pinned Locked Moved General and Desktop
33 Posts 5 Posters 17.6k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • freddy311082F Offline
    freddy311082F Offline
    freddy311082
    wrote on last edited by
    #2

    sorry.... the code was not pasted well...

    here is my code again
    @
    QFile file("/home/freddy/Trabajo/bpg/diseno/rubro 7.xlsx");
    if (!file.open(QIODevice::ReadOnly))
    {
    std::cout <<"error" << std::endl;
    exit(0);
    }

    QByteArray bytes = file.readAll();
    file.close();
    QString allBytes;
    for(int i = 0; i < bytes.length(); i++)
    allBytes+= bytes.at(i);
    qDebug(allBytes.toLatin1());
    @

    best regards

    [code tags added, koahnig]

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #3

      Hi,

      .xlsx is a compressed file format. You can't convert it directly to a string because its data is not plain text. (If you try to open the .xlsx file with a text editor, you will see garbage values).

      If you create a .txt file and write some text inside, you can convert the bytes directly to a string.

      By the way, add '@' before and after your code to make it easier to read. If you make a mistake, you can click "edit" on the right -- you don't need to post twice.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • freddy311082F Offline
        freddy311082F Offline
        freddy311082
        wrote on last edited by
        #4

        Thank for answer JKSH and sorry for the code... I didn't know about @.

        I just need the binary data from file in a QString.... is that possible ?

        I had open an xlsx file as example, but I need to do this with any kinf of files: PDF, JPEG, PNG or anyone

        is that possible ??

        thanks

        1 Reply Last reply
        0
        • S Offline
          S Offline
          ScottR
          wrote on last edited by
          #5

          Binary data is not "print"-able. Do a google search for "how to output binary data".

          http://www.qtforum.org/article/19923/how-to-dump-a-qbytearray-to-a-qstring-with-one-sentence.html

          1 Reply Last reply
          0
          • SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #6

            Edit: only repeated the same thing as my fellows, sorry

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #7

              [quote author="freddy311082" date="1390831690"]Thank for answer JKSH and sorry for the code... I didn't know about @.[/quote]That's ok :) Thank you for editing your posts.

              [quote]I just need the binary data from file in a QString....[/quote]Why?

              If you have binary data, it's best to store it as binary data (QByteArray). It doesn't make sense to put non-strings inside QString.

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              1 Reply Last reply
              0
              • freddy311082F Offline
                freddy311082F Offline
                freddy311082
                wrote on last edited by
                #8

                well JKSH...

                i need put the binary data in a QString because I'm trying to save a file into PostgreSQL databse.... to make that, I need to pass a query string to QSqlDatabse::exec() method and for that, I need to pass it a QString...

                let me show what I'm doing:

                @
                QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
                db.setHostName("localhost");
                db.setPort(5432);
                db.setDatabaseName("bpg");
                db.setUserName("postgres");
                db.setPassword("");
                if (db.open())
                {
                QFile file("/home/freddy/Trabajo/bpg/diseno/rubro 7.xlsx");
                if (!file.open(QIODevice::ReadOnly))
                {
                qDebug("file error...");
                exit(0);
                }

                    QString bytes = file.readAll();
                    file.close();
                    std::cout << "sending query..." << std::endl;
                    
                    db.exec&#40;(QString("insert int files values (66, '{"&#41;+ bytes  +"}')"));
                    db.close();
                }
                exit(EXIT_SUCCESS);
                

                @

                as you can see, into the query execution I need to pass a QString, so, I need to convert the binary file into a QString to send it to my database...

                any idea ?

                thanks anyway my friend for your answer

                freddy

                1 Reply Last reply
                0
                • JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #9

                  I see; I misunderstood your original intent, sorry.

                  You can use byteArray.toBase64() to encode your file as a binary string. toHex() works too, but produces longer strings than toBase64(). See https://qt-project.org/forums/viewthread/12281 for an example.

                  By the way, for safety, it is a good idea to use SQL bindings instead of building a string directly. See:

                  • http://qt-project.org/doc/qt-5/qsqlquery.html#approaches-to-binding-values
                  • http://xkcd.com/327/

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  1 Reply Last reply
                  0
                  • freddy311082F Offline
                    freddy311082F Offline
                    freddy311082
                    wrote on last edited by
                    #10

                    Hi JKSH

                    Thanks for your advices, they are very useful...

                    Well, as I could see, I think that the problem is not with QString and QByteArray... I think that I can make a new post with my QSqlQuery question.

                    the table files, which is where I'm trying to save the files, has only 2 filds. The first one is a fileid, who is an integer, and the second one is a bytea[], where I'm trying to save the binary file.

                    anyway, here is my code exaple of what I'm trying to do... someone in a Postgres list told me that use a query.addBindValue, I try and nothing happend.

                    here is my new code example:

                    @
                    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
                    db.setHostName("localhost");
                    db.setPort(5432);
                    db.setDatabaseName("bpg");
                    db.setUserName("postgres");
                    db.setPassword("");
                    if (db.open())
                    {
                    QFile file("/home/freddy/Trabajo/bpg/diseno/rubro 7.xlsx");
                    if (!file.open(QIODevice::ReadOnly))
                    {
                    qDebug("file error...");
                    exit(0);
                    }
                    QByteArray bytesArr;
                    QBuffer buffer(&bytesArr);
                    buffer.open(QBuffer::ReadWrite);
                    buffer.write(file.readAll());
                    std::cout << "sending query..." << std::endl;

                        QSqlQuery query(db);
                        query.prepare("insert into files values(:id,:data)");
                        query.bindValue(":id",18);
                        query.bindValue(":data",bytesArr.toHex());
                        //query.addBindValue(bytesArr.toHex());
                        if (!query.exec&#40;&#41;)
                        {
                            qDebug(query.lastError().driverText().toLatin1());
                        }
                        cout << "query sent..." << endl;
                        file.close();
                        db.close();
                    }
                    

                    @

                    and this is the output of my program:

                    @
                    sending query...
                    QPSQL: Unable to create query
                    query sent...
                    Unable to free statement: connection pointer is NULL

                    *** Exited normally ***
                    @

                    do you remomend me that open a new post or continue here ??

                    what i'm do wrong ??

                    best regards

                    1 Reply Last reply
                    0
                    • JKSHJ Offline
                      JKSHJ Offline
                      JKSH
                      Moderators
                      wrote on last edited by
                      #11

                      You're welcome :)
                      [quote]
                      @
                      query.prepare("insert into files values(:id,:data)");
                      @
                      [/quote]Your string shouldn't have ':'

                      Check the QSqlQuery documentation again.
                      [quote]
                      @
                      QByteArray bytesArr;
                      QBuffer buffer(&bytesArr);
                      buffer.open(QBuffer::ReadWrite);
                      buffer.write(file.readAll());
                      @
                      [/quote]The buffer is unnecessary. Just read your QFile straight into your QByteArray.

                      [quote]
                      @
                      query.bindValue(":data",bytesArr.toHex());
                      @
                      [/quote]I'm not sure how the bytea type works. Maybe you can save space by using toBase64() instead of toHex(), and store your data in a string column? (I don't use PostgreSQL)

                      [quote]do you remomend me that open a new post or continue here ??[/quote]You can continue posting here, since this is your actual question. Just edit your original post to change the title.

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      1 Reply Last reply
                      0
                      • TheBadgerT Offline
                        TheBadgerT Offline
                        TheBadger
                        wrote on last edited by
                        #12

                        You can do the following to store a QByteArray directly in PostgreSQL:
                        @
                        // Create QSqlField type for your byte array
                        QSqlField byteField("Data", QVariant::ByteArray);
                        // Set the data in the QSqlField
                        byteField.setValue(bytesArr);
                        // Create the query
                        QString queryString = QString("INSERT INTO files VALUES(%1, %2);")
                        .arg(18)
                        .arg(db.driver()->formatValue(byteField));
                        // Execute the query
                        query.exec(queryString);
                        @

                        Then in PostgreSQL the column type should be BYTEA.

                        Hope this helps (its the way that I am doing it)


                        Check out my SpellChecker Plugin for Qt Creator @ https://github.com/CJCombrink/SpellChecker-Plugin

                        1 Reply Last reply
                        0
                        • TheBadgerT Offline
                          TheBadgerT Offline
                          TheBadger
                          wrote on last edited by
                          #13

                          To continue on my previous post:
                          To read the data again you just do:
                          @
                          // Query
                          query.exec("SELECT id, data FROM files LIMIT 1");
                          query.next();
                          QByteArray dataArray = query.value(query.record().indexOf("data")).toByteArray();
                          @

                          That should do it.


                          Check out my SpellChecker Plugin for Qt Creator @ https://github.com/CJCombrink/SpellChecker-Plugin

                          1 Reply Last reply
                          0
                          • freddy311082F Offline
                            freddy311082F Offline
                            freddy311082
                            wrote on last edited by
                            #14

                            Thanks for help for everybody for your help...

                            I had change the post name as JKSH recomend...

                            well Badger, your solution doesn't work my friend... I have try this:

                            @
                            QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
                            db.setHostName("localhost");
                            db.setPort(5432);
                            db.setDatabaseName("bpg");
                            db.setUserName("postgres");
                            db.setPassword("");
                            if (db.open())
                            {
                            QFile file("/home/freddy/Trabajo/bpg/diseno/rubro 7.xlsx");
                            if (!file.open(QIODevice::ReadOnly))
                            {
                            qDebug("file error...");
                            exit(0);
                            }
                            QByteArray bytesArr(file.readAll());
                            std::cout << "sending query..." << std::endl;
                            QSqlField byteField("filedata",QVariant::ByteArray);
                            QString queryStr = QString("insert into files values(%1,%2);").arg(18).arg(db.driver()->formatValue(byteField));
                            QSqlQuery query(db);
                            query.prepare(queryStr);
                            //query.addBindValue(bytesArr.toHex());
                            if (!query.exec(queryStr))
                            {
                            qDebug("query error...");
                            qDebug(query.lastError().databaseText().toLatin1());
                            }
                            cout << "query sent..." << endl;
                            file.close();
                            db.close();
                            }
                            @
                            and the output is this:
                            @
                            Starting: /home/freddy/Trabajo/bpg/kdevelop/bpg/build/bpg
                            sending query...
                            query error...
                            ERROR: array value must start with "{" or dimension information
                            LINE 1: insert into files values(18,'\x504b030414000600080000002100e...
                            ^
                            (22P02)
                            query sent...
                            *** Exited normally ***
                            @

                            I try to add a '{' to the begining of the QArrayBuffer, after append the bytesArray reading from the file, and finaly, y append to the end of the end of the array the '}' character and ther error is the same.

                            Postgres require that the data for the insert query for the bytea field must be between characters {} or with le length information at the beginin...

                            i think that the proble is exactly how put the binary field between {}... i havd try with this and the result is the same:
                            @
                            QByteArray bytesArr;
                            bytesArr.append('{');
                            bytesArr.append(file.readAll());
                            bytesArr.append('}')
                            @

                            best regards...

                            1 Reply Last reply
                            0
                            • TheBadgerT Offline
                              TheBadgerT Offline
                              TheBadger
                              wrote on last edited by
                              #15

                              That is very interesting... I cant see a difference between your code and my code (except for the application specific stuff).

                              What version of Qt are you using and PostgreSQL?
                              Mine is: Qt 4.8.1
                              PostgreSQL: 9.1

                              I am still looking into the problem, hopefully I can post an update that might help.

                              Sorry for that


                              Check out my SpellChecker Plugin for Qt Creator @ https://github.com/CJCombrink/SpellChecker-Plugin

                              1 Reply Last reply
                              0
                              • freddy311082F Offline
                                freddy311082F Offline
                                freddy311082
                                wrote on last edited by
                                #16

                                That's Ok Badger...

                                I'm using Qt5.2, Postgres 9.3 and Archlinux.

                                I have try with the post which told me JKSH but the problem still remain. The problem is how I can put the binary data between {} for postgres query....

                                1 Reply Last reply
                                0
                                • TheBadgerT Offline
                                  TheBadgerT Offline
                                  TheBadger
                                  wrote on last edited by
                                  #17

                                  Quick though, try:
                                  @
                                  QString queryStr = QString("insert into files values(%1,'%2');").arg(18).arg(db.driver()->formatValue(byteField));
                                  @
                                  or
                                  @
                                  QString queryStr = QString("insert into files values(%1,'{%2}');").arg(18).arg(db.driver()->formatValue(byteField));
                                  @

                                  or something based on the second without the quotes.


                                  Check out my SpellChecker Plugin for Qt Creator @ https://github.com/CJCombrink/SpellChecker-Plugin

                                  1 Reply Last reply
                                  0
                                  • freddy311082F Offline
                                    freddy311082F Offline
                                    freddy311082
                                    wrote on last edited by
                                    #18

                                    with the first code the output is this:
                                    @
                                    Starting: /home/freddy/Trabajo/bpg/kdevelop/bpg/build/bpg
                                    sending query...
                                    query error...
                                    ERROR: syntax error at or near ""
                                    LINE 1: insert into files values(18,''\x504b030414000600080000002100...
                                    ^
                                    (42601)
                                    query sent...
                                    *** Exited normally ***
                                    @
                                    and with the second is this one:
                                    @
                                    Starting: /home/freddy/Trabajo/bpg/kdevelop/bpg/build/bpg
                                    sending query...
                                    query error...
                                    ERROR: syntax error at or near ""
                                    LINE 1: insert into files values(18,'{'\x504b03041400060008000000210...
                                    ^
                                    (42601)
                                    query sent...
                                    *** Exited normally ***
                                    @

                                    1 Reply Last reply
                                    0
                                    • TheBadgerT Offline
                                      TheBadgerT Offline
                                      TheBadger
                                      wrote on last edited by
                                      #19

                                      My best guess is it is then something with the versions. An example in my PostgreSQL log of a successful query is:
                                      @
                                      SELECT SCHEMA.update_element(1, 9, '2014-1-29 16:55:03.411', '\xaaaaaaaa00000000000000000000000
                                      @

                                      (only the first part is shown, but that is out of the log, with some name updates )

                                      [edit: clicked post instead of preview]


                                      Check out my SpellChecker Plugin for Qt Creator @ https://github.com/CJCombrink/SpellChecker-Plugin

                                      1 Reply Last reply
                                      0
                                      • TheBadgerT Offline
                                        TheBadgerT Offline
                                        TheBadger
                                        wrote on last edited by
                                        #20

                                        The difference is that I am using a stored procedure in postgreSQL to update the table, the stored procedure is defined as:
                                        @
                                        CREATE OR REPLACE FUNCTION SCHEMA.update_element(
                                        nr_1 INTEGER,
                                        nr_2 INTEGER,
                                        time_arg TIMESTAMP WITH TIME ZONE,
                                        data_arg BYTEA
                                        )
                                        RETURNS VOID AS
                                        $$
                                        DECLARE
                                        BEGIN
                                        -- input into table with update
                                        END;
                                        $$
                                        @

                                        But from my limited understanding is that that should be basically the same in handling the BYTEA field.


                                        Check out my SpellChecker Plugin for Qt Creator @ https://github.com/CJCombrink/SpellChecker-Plugin

                                        1 Reply Last reply
                                        0
                                        • freddy311082F Offline
                                          freddy311082F Offline
                                          freddy311082
                                          wrote on last edited by
                                          #21

                                          yes brother... I will see in a Postgres forum

                                          thanks anyway

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt Extensions
                                          • Unsolved