我想在带有框架qt的oid类型的postgres中读取和写入像图像或视频这样的大对象。在查询中,我可以使用lo_import和lo_export来读取和写入具有特定本地地址的大对象以进行导入和导出。但问题是如何用qt和qsqlquery读写?
您可以将server side SQL functions用于大型对象,可通过SELECT
通过QSqlQuery::exec()
语句调用。
要一次读取或写入大对象,请参阅lo_get
和lo_put
。
如果二进制数据足够大,你宁愿用块处理它们,启动一个事务,然后在循环中使用lo_open
,loread
/ lowrite
,lo_close
......
发送和检索的二进制数据的PostgreSQL类型是bytea
。当使用QSql::Binary
绑定输入参数时,应使用QSqlQuery
,以便驱动程序在需要时相应地转义数据。
假设您有一个名为“my_table”的表。对于使用PostgreSQL存储大型二进制对象,建议使用bytea
类型作为数据字段,因此将其命名为“binary_data”。
要插入数据我会使用QSqlRecord
,如下所示:
QSqlTableModel *model;
QSqlDatabase m_database;
m_database = ...//connect to the database here
model = new QSqlTableModel(0, m_database);
model->setTable("my_table");
model->select();
QSqlRecord rec;
rec = model->record();
QFile f("path_to_a_big_file");
if(f.open(QIODevice::ReadOnly))
{
QByteArray ba = f.readAll();
rec.setValue("binary_data",ba.toBase64());
}
model->insertRecord(-1,rec);
model->submitAll();
要更新数据QSqlQuery
将:
QSqlQuery query(m_database);
query.prepare("update my_table set binary_data = :binary_data where [condition]....");
QFile f("path_to_a_big_file");
if(f.open(QIODevice::ReadOnly))
{
QByteArray ba = f.readAll();
query.bindValue(":binary_data",ba.toBase64());
}
query.exec();
最后要阅读你需要做的事情:
QSqlTableModel *model;
model = new QSqlTableModel(0, m_database);
model->setTable("my_table");
model->select();
while(model->canFetchMore())
model->fetchMore();
for (int i = 0; i < model->rowCount(); ++i)
{
QByteArray ba = QByteArray::fromBase64(model->record(i).value("binary_data").toByteArray())
//do something with the retrieved data
}
另请注意,您有责任记住放在表格中的文件类型。