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.
  • J Offline
    J Offline
    JKSH
    Moderators
    wrote on 27 Jan 2014, 14:02 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
    • F Offline
      F Offline
      freddy311082
      wrote on 27 Jan 2014, 14:08 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 27 Jan 2014, 14:19 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
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 27 Jan 2014, 14:20 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
          • J Offline
            J Offline
            JKSH
            Moderators
            wrote on 27 Jan 2014, 14:41 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
            • F Offline
              F Offline
              freddy311082
              wrote on 27 Jan 2014, 19:21 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
              • J Offline
                J Offline
                JKSH
                Moderators
                wrote on 28 Jan 2014, 00:02 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
                • F Offline
                  F Offline
                  freddy311082
                  wrote on 28 Jan 2014, 21:21 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
                  • J Offline
                    J Offline
                    JKSH
                    Moderators
                    wrote on 28 Jan 2014, 22:36 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
                    • T Offline
                      T Offline
                      TheBadger
                      wrote on 29 Jan 2014, 09:02 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
                      • T Offline
                        T Offline
                        TheBadger
                        wrote on 29 Jan 2014, 09:08 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
                        • F Offline
                          F Offline
                          freddy311082
                          wrote on 29 Jan 2014, 14:19 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
                          • T Offline
                            T Offline
                            TheBadger
                            wrote on 29 Jan 2014, 14:40 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
                            • F Offline
                              F Offline
                              freddy311082
                              wrote on 29 Jan 2014, 14:45 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
                              • T Offline
                                T Offline
                                TheBadger
                                wrote on 29 Jan 2014, 14:50 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
                                • F Offline
                                  F Offline
                                  freddy311082
                                  wrote on 29 Jan 2014, 14:56 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
                                  • T Offline
                                    T Offline
                                    TheBadger
                                    wrote on 29 Jan 2014, 14:59 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
                                    • T Offline
                                      T Offline
                                      TheBadger
                                      wrote on 29 Jan 2014, 15:04 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
                                      • F Offline
                                        F Offline
                                        freddy311082
                                        wrote on 29 Jan 2014, 15:20 last edited by
                                        #21

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

                                        thanks anyway

                                        1 Reply Last reply
                                        0
                                        • T Offline
                                          T Offline
                                          TheBadger
                                          wrote on 29 Jan 2014, 15:21 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

                                          12/33

                                          29 Jan 2014, 09:02

                                          • Login

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