Making Postgres Only Diesel Code To Also Support Sqlite

I am adding local sync support to fifthtry, where in users of fifthtry would be able to keep a local version of content they own, and they can locally edit them, and sync them with server.

Fifthtry itself is written with diesel. This post describes some of the struggles I had to face.

Conditional Compilation

I started with features postgres and sqlite for top level crates.

The crate powering the website worked against postgres where as local binary against sqlite.


realm = {path = "../realm", features=["sqlite", "sqlite_default"]}

fifthtry_common = { path = "../fifthtry_common", features=["sqlite"]}
fifthtry_db = {path = "../fifthtry_db", features=["sqlite"]}

Similarly fifthtry/Cargo.toml activated postgres feature everywhere.

For crates that supported both postgres and sqlite, they had to pass the feature flag to their dependencies based on which feature flag was activated, eg fifthtry_db/Cargo.toml:

default = []
sqlite = ["realm/sqlite", "realm/sqlite_default", "diesel/sqlite"]
postgres = ["realm/postgres", "realm/postgres_default", "diesel/postgres"]

Which is saying if feature “sqlite” for fifthtry_db is activated, activate “sqlite” and “sqlite_default” for “realm” crate, and “sqlite” for “diesel” crate and similar for postgres.

Say Goodbye to cargo check --all

In my workspace I had both fifthtry and fifthtry_local (and crates to support them).

I used to use cargo check --all to check both fifthtry and fifthtry_local. After I added Postgres and sqlite features, I could not use --all as it seems to compile with features postgres and sqlite activated.

Now I check using cargo check; cd fifthtry_local; cargo check -p fifthtry_local; cd -. This has increased overall check time.

Bool Not Supported in Sqlite - Diesel

I had a bunch of columns with datatype Bool, which for some reason do not work with diesel print-schema.

Converted all of them to i32/IntegerField.

citext is postgresql only

I used citext for representing username/team_name on fifthtry.


Timestampz vs Timestamp

Postgres support a column type timestampz, which support timestamp along with timezone information. Sqlite does not, it only has timestamp.

Diesel + Chrono support timestampz on rust side using rust type DateTime<Utc>, where as timestamp to NaiveDateTime.

This posed particular problem, a lot of function used DateTime<Utc> as input and output parameters.

I chose to let the function signatures be, converted the data between DateTime<Utc> and NaiveDateTime before/after passing to diesel.

#[cfg(feature = "sqlite")]
pub fn datetime(d: DateTime<Utc>) -> NaiveDateTime {

#[cfg(feature = "postgres")]
pub fn datetime(d: DateTime<Utc>) -> DateTime<Utc> {

This datetime converter helped me convert DateTime<Utc> to either DateTime<Utc> or NaiveDateTime depending on what I am compiling against.

I got lucky that I had to support only one backend at crate level.

Table Of Content

Immobile v2


Rust: Or Type

Link Log

August 2020

July 2020

June 2020

May 2020

April 2020

March 2020

February 2020

January 2020


Books Have Read / Recommend

Product Management Books

Badass: Making Users Awesome


Five Cs of An Organisation

Success and failure of encryption

Open Source

Observer: Observability for Rust

Realm: Web Development Framework Using Rust and Elm

MartD: Server To Browser Messages

On Writing And Formats Of Written Communications

Rust Stuff

Rust feature flags

Why is diesel not compatible with async?

Making Postgres Only Diesel Code To Also Support Sqlite

Rust Git2’s Concepts

Git Hash And Build Date In Rust Build

Systray Only Native App In Rust

Software and Tools I Use Often


DNS Over HTTPS Controversy

The Patel Motel Cartel

Standalone Complex


January 2020

Word Of The Day





Nix On OSX Catalina

Postgres: WAL / Logical Decoding

Postgres: Listen-Notify



Go All The Way

SSH Commands



Nu Shell

SHA256 vs SHA224

Pronouns Bad


Web Components

Early Return