Russian Qt Forum

Qt => Базы данных => Тема начата: sergek от Апрель 09, 2015, 13:22



Название: [РЕШЕНО] Variant в PostgreSQL
Отправлено: sergek от Апрель 09, 2015, 13:22
Коллеги, мне нужно в таблицу записать, а потом прочитать значение переменной типа QVariant.
Как это можно сделать? Пока вижу 2 варианта: создать таблицу с несколькими полями ожидаемых типов, либо использовать строковое (а может bytea) поле, куда записывать сериализованный через QDataStream QVariant.
Может, с этим кто-нибудь уже сталкивался и решение совсем простое?


Название: Re: Variant в PostgreSQL
Отправлено: PimenS от Апрель 09, 2015, 14:03
Можно и записывать и читать через QSqlQuery.


Название: Re: Variant в PostgreSQL
Отправлено: sergek от Апрель 09, 2015, 15:58
Можно и записывать и читать через QSqlQuery.
:)

UPD. Не, строковое представление, наверное, не пойдет - с кодировками будут проблемы.


Название: Re: Variant в PostgreSQL
Отправлено: PimenS от Апрель 09, 2015, 19:28
Почему может быть проблема с кодировками? Использую сервера PostgreSQL на win и debian, на клиентских стоят win xp, win 7, win 8, ubuntu 12.04/14.04.
Ни разу проблем с кодировкой не возникло, ни при записи QVariant::String в varchar или text, ни при считывании.
Есть вариант, что с при записи timestamp возникнут разногласия (не ковырял, но мне хватает QDateTime::toString).
Еще при записи QUuid в uuid могут возникать проблемы при записи как QVariant::Uuid, тоже легко решается через QUuid::toString.


Название: Re: Variant в PostgreSQL
Отправлено: sergek от Апрель 09, 2015, 22:06
Примерно так:
Код:
    CREATE TABLE variant
    (
      id serial NOT NULL,
      variant bytea
    );

Код:
    QVariant var = QDateTime::currentDateTime();
//    QVariant var = 1234567;
//    QVariant var = 1234.5678;
//    QVariant var = true;
    QByteArray arr;
    QDataStream out(&arr,QIODevice::WriteOnly);
    out << var;

    textEdit->append(QString("in = %1").arg(var.toString()));

    QSqlQuery query(db);
    query.prepare("INSERT INTO variant(variant) VALUES (:variant)");
    query.bindValue(":variant", arr);
    query.exec();
    int id = query.lastInsertId().toInt();

    // -------------

    query.prepare("select * from variant where id = :id");
    query.bindValue(":id", id);
    query.exec();

    query.next();
    QSqlRecord rec = query.record();

    QByteArray arr2 = query.value(rec.indexOf("variant")).toByteArray();
    QDataStream in(&arr2,QIODevice::ReadOnly);
    QVariant var2 = QVariant(in);

    textEdit->append(QString("out = %1").arg(var2.toString()));


Название: Re: Variant в PostgreSQL
Отправлено: PimenS от Апрель 09, 2015, 23:28
Не понял к чему этот пример.

Для чего вот это?

Код:
    QVariant var = QDateTime::currentDateTime();
//    QVariant var = 1234567;
//    QVariant var = 1234.5678;
//    QVariant var = true;
    QByteArray arr;
    QDataStream out(&arr,QIODevice::WriteOnly);
    out << var;

Зачем вообще в данном примере QByteArray и QDataStream? Зачем в базе хранить строковый тип в двоичном виде? У PostgreSQL для строковых данных вполне хватает типов.
Почему нельзя сделать просто так:

Код:

    textEdit->append(QString("in = %1").arg(QDateTime::currentDateTime().toString()));

    QSqlQuery query(db);
    query.prepare("INSERT INTO variant(variant) VALUES (?)");
    query.addBindValue(textEdit);
    query.exec();



Название: Re: Variant в PostgreSQL
Отправлено: gil9red от Апрель 09, 2015, 23:51
Код:

    textEdit->append(QString("in = %1").arg(QDateTime::currentDateTime().toString()));

    QSqlQuery query(db);
    query.prepare("INSERT INTO variant(variant) VALUES (?)");
    query.addBindValue(textEdit);
    query.exec();

textEdit это же не QTextEdit, а QString?


Название: Re: Variant в PostgreSQL
Отправлено: PimenS от Апрель 10, 2015, 00:00
Код:

    textEdit->append(QString("in = %1").arg(QDateTime::currentDateTime().toString()));

    QSqlQuery query(db);
    query.prepare("INSERT INTO variant(variant) VALUES (?)");
    query.addBindValue(textEdit);
    query.exec();

textEdit это же не QTextEdit, а QString?

Из примера непонятно, что это. Если это QTextEdit, то разница не велика query.addBindValue(textEdit->toPlainText()); ну или toHtml()


Название: Re: Variant в PostgreSQL
Отправлено: sergek от Апрель 10, 2015, 09:04
textEdit это QTextEdit. Это неудачный пример (судя по реакции), который отображает строковое представление переменной QVariant.
В БД мне не нужно хранить строку, а переменную типа QVariant. В ней может быть что угодно - дата, целое, изображение. Нужно записать эту переменную в таблицу, а потом прочитать и опять вернуть в переменную QVariant, с сохранением типа данных.
Ну, раз нет больше ответов, кроме вопросов, тему закрываю.