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.5k 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.
  • 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
                                  • TheBadgerT Offline
                                    TheBadgerT Offline
                                    TheBadger
                                    wrote on last edited by
                                    #22

                                    My conclusion is PostgreSQL version change that made this happen (I might be wrong).

                                    My code:
                                    @
                                    QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
                                    /* Set the default values for the database connection */
                                    db.setHostName("127.0.0.1");
                                    db.setPort(5432);
                                    db.setDatabaseName("my_db");
                                    db.setUserName("postgres");
                                    db.setPassword("postgres");

                                    if (db.open())
                                    {
                                        QByteArray bytesArr("Some test byte array");
                                        qDebug() << "sending query...";
                                        QSqlField byteField("filedata", QVariant::ByteArray);
                                        byteField.setValue(bytesArr); // need this
                                        QString queryStr = QString("INSERT INTO files VALUES(%1,%2);")
                                                           .arg(18)
                                                           .arg(db.driver()->formatValue(byteField));
                                        QSqlQuery query(db);
                                        query.prepare(queryStr);
                                    
                                        qDebug() << "Query: " << queryStr;
                                        //query.addBindValue(bytesArr.toHex());
                                        if (!query.exec&#40;queryStr&#41;&#41;
                                        {
                                            qDebug("query error...");
                                            qDebug(query.lastError().databaseText().toLatin1());
                                        } else {
                                            qDebug() << "query sent...";
                                        }
                                        db.close();
                                    }
                                    

                                    @

                                    My output:
                                    @
                                    sending query...
                                    Query: "INSERT INTO files VALUES(18,'\x536f6d6520746573742062797465206172726179');"
                                    query sent...
                                    @

                                    The result, an updated column in my database.

                                    Somewhere I think there is a version incompatibility. Perhaps one can make a bug request on some place, not sure where the solution should be.

                                    Good luck, these types of problems are very annoying.

                                    [edit: took out IP and db name]


                                    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
                                      #23

                                      Me again :P

                                      Try something like this, to check the PostgreSQL server:
                                      @
                                      QString hackedString;
                                      hackedString = db.driver()->formatValue(byteField);
                                      hackedString.insert(1, '{');
                                      hackedString.insert(hackedString.length() - 1, '}');
                                      qDebug() << "hacked string: " << hackedString;
                                      QString queryStr = QString("INSERT INTO files VALUES(%1,%2);")
                                      .arg(18)
                                      .arg(hackedString);
                                      @

                                      *just replace the relevant code in your code.

                                      The string looks fine according to what the error says, but my server responds with "ERROR: invalid input syntax for type bytea".


                                      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
                                        #24

                                        YES MY FRIEND !!! THAT IS THE SOLUTION !!!

                                        THANKS !!!!

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

                                          Its a hack... but if it works :/

                                          I think the Qt PostgreSQL Driver code might need to be updated to support the BYTEA field in the latest PostgreSQL versions (this is just a thought).

                                          Glad I could have helped.


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

                                          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