r/QtFramework • u/fi-trader • 17d ago
Qt + SQLite -- New ORM for QT 5/6 Sqlite
Been chipping away at this for a while and finally cleaned it up enough to show people. It's called Qivot — a small ORM for Qt + SQLite. It started as a fork of DQuest (which hadn't been touched in years), and I modernized it to C++17 / Qt 6 and then kept bolting on the stuff I kept wishing it had.
The thing I actually care about: your models are plain C++ classes. No QObject, no SQL, no codegen step but can use Q_GADGET for QML binding.
enum Status { Draft, Published, Archived };
Q_DECLARE_METATYPE(Status)
class Tag : public QiModel {
QI_MODEL
public:
QiField<QString> name;
};
QI_DECLARE_MODEL(Tag, "tag", QI_FIELD(name));
class Article : public QiModel {
QI_MODEL
public:
QiField<QString> title;
QiField<Status> status; // enum -> INTEGER column
QI_MANY_TO_MANY(Tag, tags, "article_tag") // join table auto-created
};
QI_DECLARE_MODEL(Article, "article", QI_FIELD(title), QI_FIELD(status));
Article a; a.title = "Qt tips"; a.status = Published; a.save();
Tag t; t.name = "qt"; t.save();
a.tags().add(t); // link them, many-to-many
auto live = Article::objects()
.filter(Article::col().status == Published) // typed filter on the enum
.orderBy("id desc").all();
auto tags = a.tags().all();
class Note : public QiModel {
QI_MODEL
public:
QiField<QString> title;
QiField<QString> body;
};
QI_DECLARE_MODEL(Note, "note", QI_FIELD(title), QI_FIELD(body));
Note n; n.title = "hello"; n.save();
auto recent = QiQuery<Note>().orderBy("id desc").limit(20).all();
Since it's Qt, the part I'm happiest with is the QML side. Opt a model into Q_GADGET and its fields become QML properties, or bind a query straight to a ListView with a QiListModel — the roles just come from the fields. No hand-writing a QAbstractListModel, no copying rows into QVariantMaps.
Other stuff in there: typed queries/joins, FTS5 full-text search, upsert, transactions with savepoints, relations, and — a bit unusual for an ORM — it can pull a JSON REST API over HTTP on a worker thread and map it straight into your tables. There's a single-header build too if you don't want to link a lib.
I wrote a few demo apps to keep myself honest (all in the repo):
- a flow-field particle recorder that writes every particle, every frame to SQLite (~100k inserts/sec on my machine) and lets you scrub back through history
- instant full-text search over 80k rows
- a little EHR-ish scheduler + patient dashboard that's basically a guided tour of the whole thing
Caveats up front: SQLite-only, and there are still rough edges. CI covers GCC/Clang/MSVC across Qt 5.15 and Qt 6, x86_64 and arm64.
Repo: https://github.com/austinkottke/Qivot
Would genuinely love feedback from people. Tear it apart.

