ORM & Data Access — Cross-Language Comparison

This note compares the data-access models a programmer actually picks between when wiring an application to a database — raw drivers vs query builders vs full ORMs vs document/KV clients vs graph drivers vs CDC/ETL vs type-safe Rust-style — across the 53 deep language notes plus the major DB engines. Each section has a unified table mapping libraries onto the axes (query complexity, type safety, migration story, async support, learning curve). The closing decision tree picks the right tool from query complexity + database type + team familiarity.

See also

1. The six layers

Every application’s data-access lives on a layered spectrum from raw protocol to high-abstraction ORM. Most apps mix layers — raw driver for hot paths, ORM for CRUD admin.

LayerWhat you writeAbstractionType safetyLatency overhead
Raw driverSQL strings + parameter bindingvery lownone at compile time~zero
Query builderfluent API → SQLlowpartial (sometimes; depends on lang)low
Code-first ORM (Active Record)User.find(1)highpartialmedium
Code-first ORM (Data Mapper)repository + entity managerhighpartial-to-fullmedium
DB-first / schema-first ORMscan DB → generate typeshighfull at compile timemedium
Type-safe SQL buildercompile-time-checked SQLhighfulllow

The 2018+ trend is toward layer 6 — compile-time-checked SQL (Diesel, jOOQ, sqlx, Drizzle, Prisma SQL queries) — combining ORM ergonomics with raw-driver performance and full type safety.

2. Raw database drivers

The protocol-level libraries. Hot-path code, ETL workers, and ops scripts often stop here.

DriverDatabaseLanguageSync/AsyncNotesLinked note
libpqPostgreSQLCsyncthe reference; everything binds to itc
psycopg2 / psycopg3PostgreSQLPythonpsycopg2: sync; psycopg3: bothpsycopg3 (2021+) is canonical; supports async + connection poolpython
asyncpgPostgreSQLPythonasyncdirect protocol implementation; ~2× faster than psycopg3 asyncpython
node-postgres (pg)PostgreSQLNode.jsasyncde facto Node Postgres clientjavascript
postgres.jsPostgreSQLNode.jsasyncnewer; tagged-template SQL, faster than pgjavascript
JDBCuniversalJavasync (Loom virtual threads enable scaling)the standard JVM database APIjava
HikariCPuniversalJavasyncthe dominant JVM connection pooljava
JDBIuniversalJavasyncthin layer atop JDBC; row-mapper conveniencejava
R2DBCuniversalJavaasync (Reactive Streams)reactive JDBC alternative; mostly displaced by virtual threadsjava
ADO.NETuniversalC# / VB.NETsync + asyncthe .NET DB API; SqlClient, Npgsql, MySqlConnectorcsharp
NpgsqlPostgreSQL.NETasynchigh-quality .NET Postgres drivercsharp
pqPostgreSQLGosync (Go-style “sync”)deprecated for pgx in 2023+go
pgx (jackc/pgx)PostgreSQLGosyncthe modern Go Postgres driver; high performancego
database/sqluniversalGosyncstdlib interface; drivers registergo
postgres crate / tokio-postgresPostgreSQLRustbothsync + tokio asyncrust
mysql / mysql_async crateMySQLRustbothsimilarrust
mysql-connector-pythonMySQLPythonsyncOracle’s official clientpython
PyMySQL / aiomysqlMySQLPythonsync / asynccommunity alternativespython
pymongo / motorMongoDBPythonsync / asyncmotor is asyncio wrapperpython
mongo-go-driverMongoDBGosyncofficial Mongo Go drivergo
mongoose (driver underlying)MongoDBJSasynctypical Node Mongo pathjavascript
redis-py / aioredis (now redis-py 4.5+)RedisPythonsync / asyncmerged into redis-py 4.5+python
ioredis / node-redisRedisJSasyncNode Redis clientsjavascript
jedis / lettuceRedisJavasync / asyncJava clients; lettuce is reactivejava
sqlx (Rust)universalRustasyncalso a query-builder; compile-time SQL checkingrust
DBIuniversalPerlsyncPerl’s standard DB APIperl
DBD::* driversuniversalPerlsyncDBI driver layerperl
DBI / DBDuniversalRubysyncolder Ruby pattern (mostly replaced by AR)ruby
pg / mysql2universalRubysynclow-level Ruby drivers (used by AR)ruby
Tcl TdbcuniversalTclsyncTcl DB APItcl
Database ToolboxuniversalMATLABsyncMATLAB DB connectivitymatlab
LibPQ.jl / SQLite.jl / MySQL.jluniversalJuliasyncJulia low-level driversjulia

3. Query builders

A composable fluent API that generates SQL. Less abstraction than an ORM; more ergonomics than raw strings.

BuilderLanguageDatabaseNotesLinked note
Knex.jsNode.js (JS/TS)universalthe OG JS query builder; pluggable migration systemjavascript
SQLAlchemy CorePythonuniversalthe bottom half of SQLAlchemy without ORMpython
DieselRustPG/MySQL/SQLitecompile-time-checked schema → DSL; type-safe resultsrust
sqlxRustPG/MySQL/SQLite/MSSQLinline SQL with query! macro compile-time checked against DB schemarust
sea-orm / sea-queryRustPG/MySQL/SQLite/MSSQLdynamic query builder + Active Record-style ORMrust
entGouniversalcode-generated from schema; type-safe relationsgo
squirrelGouniversalfluent SQL buildergo
goquGouniversalsimilargo
jOOQJavauniversalDB-first; type-safe SQL DSL; gold standard for typed SQL on JVMjava
SlickScalauniversalfunctional-relational mapping; query is FP-composedscala
QuillScalauniversalquoted DSL; compile-time SQL generation; supports cats-effect / ZIOscala
DoobieScalauniversalfunctional JDBC, no ORM; FS2 streams for resultsscala
persistent + esqueletoHaskelluniversaltyped Haskell DSL; esqueleto for joinshaskell
opaleye / rel8HaskellPostgreSQLtype-safe relational algebrahaskell
BeamHaskelluniversaltype-safe ORM + builderhaskell
kyselyNode.js (TS)universalstrongly-typed query builder (compile-time schema)typescript
drizzle-ormNode.js (TS)universalTS-first; schema-as-types; lighter than Prismatypescript
dbatoolsPowerShellSQL Servermanagement toolkitpowershell

The Knex → Drizzle / Kysely shift in the TS world (2023–2025) reflects industry preference for compile-time-typed query builders over heavy ORMs. Drizzle in particular has eaten Prisma’s mindshare for greenfield TS projects.

4. Full ORMs

Object-Relational Mappers — your domain objects are persistence-aware (Active Record) or kept ignorant via a repository (Data Mapper).

4.1 Active Record style (objects = rows, no repository)

ORMLanguagePatternNotesLinked note
Rails ActiveRecordRubyActive Recordthe canonical AR pattern; Rails 7.2+ruby
SequelRubyActive Record (lighter)alternative to ActiveRecord; thinnerruby
EloquentPHPActive RecordLaravel ORMphp
Django ORMPythonActive Record + manager patternDjango frameworkpython
PeeweePythonActive Recordsmaller framework-independentpython
GORMGoActive Recordthe popular Go ORMgo
TypeORMNode.js (TS/JS)Active Record or Data Mapperdecorators + entities; struggling for maintenancetypescript
SequelizeNode.js (JS)Active Recordolder Node ORM; large communityjavascript
Mikro-ORMNode.js (TS)Data Mapper + Unit of WorkTypeScript-first; identity maptypescript
Diesel-ARRustnot really AR; closer to query builder(Diesel is hybrid)rust
CakePHP ORMPHPActive RecordCakePHP frameworkphp

4.2 Data Mapper style (repository + entity manager)

ORMLanguagePatternNotesLinked note
SQLAlchemy ORMPythonData Mapper + Unit of Work2.0+ async; the de facto Python ORMpython
HibernateJavaData Mapper + Unit of Workthe JVM gold standard since 2001; JPA referencejava
JPA (Jakarta Persistence)JavaData Mapper specspec; implemented by Hibernate, EclipseLink, OpenJPAjava
Spring Data JPAJavarepository + JPASpring Boot integrationjava
EclipseLinkJavaJPA implalternative to Hibernatejava
DoctrinePHPData Mapper + Unit of WorkSymfony’s ORM; identity mapphp
Entity Framework Core (EF Core)C# / .NETData Mapper + Unit of WorkEF Core 8/9 ships native AOT supportcsharp
DapperC# / .NETmicro-ORM (closer to query)StackOverflow-built; SQL + mapcsharp
PrismaTS / Node.jsdata mapper-ish (custom)schema.prisma → generated clienttypescript
DrizzleTS / Node.jsquery builder + light mapper(overlaps query-builder)typescript

4.3 Schema-first / code-gen

ToolLanguageNotesLinked note
PrismaTS / JSschema.prisma → typed client + migrations; v5+typescript
entGoGo schema as code → ORMgo
EdgeDB / EdgeQLuniversal client (Python, JS/TS, Go, Rust)new DB + ORM hybrid; schema-firstn/a
sqlcGowrite SQL + sqlc generates type-safe Gogo
Atlasuniversalschema-as-code migrationsn/a
dbml + dbmateuniversalschema description languagen/a

5. Document and key-value clients

NoSQL has its own access pattern — direct client libraries, not ORMs (sometimes ODM — Object Document Mapper).

LibraryDBLanguageNotesLinked note
PyMongoMongoDBPythonsyncpython
MotorMongoDBPythonasync wrapper around PyMongopython
BeanieMongoDBPythonasync ODM atop Motor + Pydanticpython
MongooseMongoDBNode.jsthe canonical Mongo ODMjavascript
MongoDB.NET DriverMongoDBC#officialcsharp
mongo-go-driverMongoDBGoofficialgo
mongo-rust-driverMongoDBRustofficialrust
redis-pyRedisPythonmerged sync + async (since 4.5)python
node-redis / ioredisRedisJScommunity + popularjavascript
jedis / lettuceRedisJavasync + reactivejava
StackExchange.RedisRedisC#the .NET Redis clientcsharp
go-redisRedisGogithub.com/redis/go-redisgo
DynamooseDynamoDBNode.jsMongoose-style ODM for DynamoDBjavascript
boto3 (DynamoDB)DynamoDBPythonlow-level AWS SDKpython
PynamoDBDynamoDBPythonPythonic ODMpython
aws-sdk DynamoDBDynamoDBJS/TS/Go/Java/Rustofficial AWS SDKsn/a
Couchbase SDKCouchbaseuniversalofficial SDKs in 10+ languagesn/a
DataStax driverCassandrauniversalDataStax C# / Java / Python / Go driversn/a
gocqlCassandraGocommunitygo
ScyllaDB driversScyllaDBuniversalCassandra-protocol-compatiblen/a
Aerospike SDKAerospikeuniversallow-latency KVn/a
etcd client / clientv3etcdGoofficial Go clientgo
consul clientConsuluniversalfor service discoveryn/a

6. Graph database clients

Graph DBs use their own query languages (Cypher, Gremlin, SPARQL, GQL, AQL). Clients usually expose those directly rather than offering a graph ORM.

LibraryDBLanguageNotesLinked note
Neo4j DriverNeo4jPython / JS / Java / Go / .NETofficial Neo4j Bolt drivers; Cypher queriessql / query
neo4j-python-driverNeo4jPythonbolt protocolpython
Spring Data Neo4jNeo4jJavarepository-style atop driverjava
Gremlin TinkerpopGremlin servers (JanusGraph, Neptune, Cosmos DB Gremlin)JVM, Python (gremlin-python), JSthe Tinkerpop APIjava
Dgraph clientsDgraphGo / Python / JSDQL queries (Dgraph Query Language)go
JanusGraphJanusGraphJVMTinkerpop-compatible; Cassandra/HBase backendjava
AWS Neptune driversNeptuneGremlin / SPARQL / openCyphermulti-protocoln/a
ArangoDB drivers (arangojs, python-arango, go-arangodb)ArangoDBuniversalAQL queriesn/a
TigerGraph driverTigerGraphuniversalGSQLn/a
Memgraph driverMemgraphuniversalBolt + Cyphern/a
CozoDBCozoDBRust + PythonDatalog flavorrust
Neo4j GraphQL ToolboxNeo4jAPINeo4j + GraphQL bridgen/a
GQL (ISO/IEC 39075:2024)universalspecthe first ISO graph-query standard, published 2024-04n/a

7. CDC, ETL, and stream-processing

For data movement (DB → DB, DB → warehouse, DB → search index). Decoupled from app code.

ToolTypeNotesLinked note
DebeziumCDC (change data capture)Postgres / MySQL / Mongo / SQL Server / Cassandra → Kafkajava
MaxwellCDCMySQL → Kafka/Kinesisjava
AirbyteELTopen-source EL connector hubjava
FivetranELTcommercial managed ELTn/a
StitchELTolder managed ELT (Talend)n/a
Materializestreaming materialized viewsPostgres-wire-compatible streaming DBn/a
Estuary Flowstreamingnewer CDC + transformationn/a
Apache Kafka Connectstreaming frameworksource + sink connectorsjava
Apache Flinkstream processingstateful streaming; SQL + DataStream APIjava
Apache Beamunified batch + streamruns on Flink, Spark, Dataflowjava
Apache Spark Structured Streamingstream processingSpark API for streamingscala
dbtanalytics ELTSQL transformations in warehousen/a
SQLMeshnewer analytics ELTvirtual environments, model-as-coden/a
Trino / Prestofederated queryquery across multiple DBsjava
Apache Iceberg / Delta Lake / Hudilakehouse table formatmetadata layer atop Parquetscala

8. Type-safe SQL — the convergence

The 2020+ shift: pull type safety as far left (closer to schema definition) as possible.

ToolLanguageMechanismCompile-time SQL checked?NotesLinked note
DieselRustschema gen → DSLyes (via schema.rs)type-safe joinsrust
sqlxRustquery! macro hits live DB during compileyes (with DATABASE_URL set at build)works with raw SQLrust
jOOQJavaDB-first code-genyes (DSL types from schema)the JVM gold standard; commercial license for some DBsjava
sqlcGowrite SQL → generates typed Goyes (parser + schema)popular in greenfield Gogo
PrismaTSschema.prisma → typed clientyes (codegen)most popular TS optiontypescript
DrizzleTSTS schema → typed builderyes (TS types)lighter than Prismatypescript
kyselyTSTS schema → typed builderyessimilartypescript
EdgeDB / EdgeQLmultischema → typed client per langyesnew DB with first-class typed accessn/a
SurrealDB SDKmultischema → typed accesspartialmulti-modeln/a
PostgREST + OpenAPIuniversalDB → REST → typed clientindirect”DB IS the API” patternn/a
Hasura GraphQL EngineuniversalDB → GraphQL → typed clientindirectsimilarn/a

The pattern is DB schema as the source of truth → type-safe client at every level. Type errors at compile time, not 3 am production page. The tradeoff: schema migrations are still hard, and breaking-change compatibility matters more (now your TS types break too).

9. Database migrations

Migrations are a separate concern that’s often bundled with the ORM/builder.

ToolLanguageNotesLinked note
AlembicPythonSQLAlchemy ecosystem; auto-generate from model diffpython
Django migrationsPythonbuilt into Django; auto-generate from modelpython
Flywayuniversal (Java)SQL-first, version-numbered filesjava
Liquibaseuniversal (Java)XML/YAML/JSON/SQL changelogsjava
Atlas (ariga.io)universaldeclarative schema-as-code; HCL or SQL; Terraform-style plan/applygo
Gooseuniversal (Go)simple SQL migrationsgo
Knex migrationsJS/TSknex.js migration runnerjavascript
Prisma MigrateTStied to Prisma schematypescript
Drizzle KitTSdrizzle migration toolkittypescript
Diesel migrationsRusttied to Diesel schemarust
EF Core MigrationsC#tied to EF Corecsharp
DbUpC#imperative SQL script runnercsharp
FluentMigratorC#fluent C# DSLcsharp
migrateGogolang-migrate; SQL filesgo
dbmateuniversallanguage-agnostic, SQL-basedn/a
sqlx migrateRustsqlx CLI migrationsrust
ActiveRecord migrationsRubybuilt into Railsruby
Doctrine MigrationsPHPDoctrine-bundledphp
Laravel migrationsPHPLaravel-bundledphp
PhinxPHPframework-agnosticphp
Ecto MigrationsElixirPhoenix-bundledelixir
SchemaSpy / pgmodeleruniversalDB visualizationn/a

The 2023+ shift: Atlas-style declarative schema-as-code is rising. You write the desired schema, the tool diffs against the live DB, generates an idempotent migration plan. Inspired by Terraform’s plan/apply.

10. Per-language data-access summary

LanguageIdiomatic stackNotesLinked note
PythonSQLAlchemy 2.0 (sync+async) + Alembic; or asyncpg + raw SQLSQLAlchemy 2.0 (2023) unified sync/async API; Pydantic 2 integrationpython
JavaScriptknex.js + raw SQL; Sequelize legacy; Mongoose for Mongoolder Node stackjavascript
TypeScriptDrizzle / Kysely (type-safe); Prisma (popular); TypeORM legacynew projects → Drizzle/Kyselytypescript
JavaSpring Data JPA + Hibernate; jOOQ for typed SQL; HikariCP pool; Flyway/Liquibase migrationsvirtual threads J21+ enable blocking JDBC at scalejava
Clibpq, libmysqlclient, sqlite3rare in modern app codec
C++libpqxx (Postgres), MySQL Connector/C++, ODBC, sqlpp11 (typed)sqlpp11 is C++ jOOQ-stylecpp
[[Languages/csharp|C#]]EF Core + LINQ; Dapper for hot paths; Npgsql; Atlas/EF migrationsEF Core 9 AOTcsharp
Gosqlc + pgx; or GORM (Active Record); ent for schema-firstsqlc + pgx dominant in 2024+go
Rustsqlx (compile-time checked) or Diesel; sea-ormsqlx most popularrust
SwiftGRDB (SQLite-focused); Vapor Fluent ORM; SwiftData (Apple); CoreData (legacy)mostly SQLite + GRDB on app sideswift
KotlinExposed (JetBrains DSL); Spring Data + Hibernate (server); KtormExposed is Kotlin-idiomatic DSLkotlin
RubyActiveRecord (canonical); Sequel; ROM (Repository pattern)Rails 7+ruby
PHPEloquent (Laravel) or Doctrine (Symfony)the two dominantphp
ScalaDoobie (FP); Slick; Quill; ScalikeJDBC; Magnum (newer)FP-effect stacks dominatescala
DartDrift (SQLite); Floor (Room-inspired); Isar; SQLDelightmostly mobile-localdart
ElixirEcto (the de-facto ORM)Ecto is widely admired for changesets + composable querieselixir
Haskellpersistent + esqueleto; opaleye / rel8; Beam; Hasqlmany options; rel8 + opaleye for typed PGhaskell
Clojurenext.jdbc (the modern API); HoneySQL (data → SQL); Toucan2next.jdbc + HoneySQL pair commonclojure
[[Languages/fsharp|F#]]SQLProvider type provider; Dapper.FSharp; FSharp.Data.SqlClienttype providers do compile-time DB schemafsharp
LuaLuaSQL; lapis.db; pgmoon (cosocket-friendly)OpenResty-friendlylua
RDBI + dplyr + dbplyr; RPostgres; data.table for analyticsdbplyr translates dplyr to SQLr
JuliaLibPQ.jl; SQLite.jl; SearchLight (Genie ORM); ODBC.jlsmall ecosystemjulia
Zigmanual; bindings to libpq + sqlite3tooling earlyzig
Nimdb_postgres + db_sqlite stdlib; norm ORMsmall ecosystemnim
Crystaldb.cr + pg.cr/mysql.cr; Granite ORMsmall ecosystemcrystal
OCamlCaqti (driver abstraction); Petrol; pgocaml (typed PG); Macaquetyped PPX-based optionsocaml
PerlDBI + DBIx::Class; Mojo::Pg / Mojo::mysqlDBIx::Class is the Perl ORMperl
Erlangepgsql; emysql; mnesia (built-in distributed DB)mnesia is unique — distributed RAM/disk DBerlang
Racketdb library (universal)thin layerracket
Common LispCL-DBI; Mito ORM; cl-postgressmall ecosystemcommon-lisp
Schemeimpl-specific (Chicken, Racket)variesscheme
Fortranrare — typically calls libpq via ISO_C_BINDINGscientific code more than enterprisefortran
COBOLembedded SQL (EXEC SQL); CICS+DB2; IMS DLImassive enterprise install basecobol
AdaGNATCOLL.SQL + GNATCOLL.Postgres; ODBCsmall ecosystemada
PascalFireDAC (Delphi); IBX; SQLdbmostly Delphi-centricpascal
PrologODBC (SWI); proSQLresearchprolog
TclTdbcthintcl
GroovySpring Data + Hibernate; GORM (Groovy ORM)JVM ecosystemgroovy
Bashpsql / mysql clients + heredocs; sqlite3 CLIops + reportingbash
PowerShelldbatools (SQL Server); Invoke-SqlcmdDBA-heavypowershell
SQLthe query language itself; stored procedures + functionsPL/pgSQL, T-SQL, PL/SQL, PL/Tclsql
Vvsql (built-in)earlyv
Odinmanual bindingssmall ecosystemodin
Rocplatform-suppliedplatform-definedroc
Gleamgleam_pgo; Cake (typed query)BEAM ecosystemgleam
Ponybindingssmall ecosystempony
Idrisresearchrareidris
Leanresearchn/alean
Coq (Rocq)researchn/acoq
Agdaresearchn/aagda
SmalltalkGlorp; image-based persistence; native object DB (Magma, GemStone)image-based persistence is uniquesmalltalk
MATLABDatabase Toolboxscientificmatlab
Mojocalls Python; native bindings earlyearlymojo

11. Recent shifts (2022–2026)

  • Type-safe queries → mainstream: Drizzle, Kysely (TS); sqlx, Diesel (Rust); sqlc (Go); jOOQ (Java); Prisma. The bar for “ORM” is rising — pure runtime ORMs without compile-time type checking feel obsolete.
  • Migration tools → declarative: Atlas (Go), schema-as-code, plan/apply. Inspired by Terraform.
  • Lakehouse table formats: Iceberg + Delta Lake + Hudi formalized the metadata layer atop Parquet (S3/GCS/ADLS object storage). Iceberg won the open standard war by 2024 (Snowflake + Databricks + AWS all back it).
  • CDC + streaming: Debezium + Kafka + Flink became the standard “DB → everything else” pattern.
  • Postgres extensions explode: pg_vector (RAG), pg_cron, pg_partman, pg_search, pgvectorscale (Timescale), TimescaleDB, PostGIS, PostgreSQL FDW for federation. “Postgres for everything” gained ground 2023–2025.
  • NewSQL distributed databases: CockroachDB (Postgres-wire), TiDB (MySQL-wire), Yugabyte, Spanner. Most expose existing drivers transparently.
  • DuckDB rise: in-process columnar analytics DB; the “SQLite of analytics”. Eats into Spark + small-warehouse use cases.
  • EdgeDB + SurrealDB: novel DBs with schema-first typed access built in from day one.
  • Hasura / PostgREST / Supabase: DB → REST/GraphQL auto-API pattern matured; smaller projects skip the backend layer entirely.
  • Vector DBs: Pinecone, Weaviate, Qdrant, Chroma, Milvus, Vald, LanceDB; pgvector also competes in this niche.
  • Java virtual threads make blocking JDBC scale — partial undoing of the R2DBC reactive push.
  • Async/await unification: SQLAlchemy 2.0 (Python), EF Core 8+ (C#), Hibernate Reactive (JVM).

Adjacent

When to pick what

Need ?
├─ Hot path / low latency / well-known queries
│   ├─ Rust → sqlx (compile-time checked) + tokio-postgres
│   ├─ Go → pgx + sqlc (generated typed Go)
│   ├─ Java → JDBC + HikariCP, or jOOQ; with virtual threads
│   ├─ C# → Dapper + ADO.NET
│   ├─ Python → asyncpg directly
│   └─ Node → postgres.js (tagged-template SQL)
├─ CRUD app with simple domain
│   ├─ Python → SQLAlchemy 2.0 + Alembic; or Django ORM
│   ├─ TS → Drizzle (light) or Prisma (popular)
│   ├─ Ruby → Rails + ActiveRecord
│   ├─ PHP → Laravel + Eloquent
│   ├─ Java → Spring Data JPA + Hibernate
│   ├─ C# → EF Core + LINQ
│   ├─ Elixir → Phoenix + Ecto
│   └─ Go → ent or GORM
├─ Complex queries (joins, CTEs, window functions, recursive)
│   ├─ JVM → jOOQ
│   ├─ Scala → Doobie or Quill
│   ├─ Haskell → opaleye/rel8 or persistent+esqueleto
│   ├─ Python → SQLAlchemy 2.0 (Core or ORM) for composition
│   ├─ Rust → Diesel or sqlx with raw SQL
│   ├─ TS → kysely or Drizzle with .with() / .with-recursive()
│   └─ Go → sqlc with raw SQL files
├─ Document DB (Mongo, Couchbase, DynamoDB)
│   ├─ Python → Beanie (Mongo, async); PynamoDB (Dynamo)
│   ├─ JS/TS → Mongoose (Mongo); Dynamoose (Dynamo)
│   ├─ Go → mongo-go-driver
│   └─ Native protocol clients (no ORM) for hot paths
├─ KV store (Redis, etcd, DynamoDB)
│   └─ Use the official driver; ORMs add little value
├─ Graph DB (Neo4j, Dgraph, Neptune, ArangoDB)
│   └─ Use the driver + Cypher / Gremlin / SPARQL / AQL / DQL directly
├─ Reactive / streaming app
│   ├─ JVM → R2DBC or virtual threads (now competitive)
│   ├─ Scala → Cats Effect + Doobie + FS2 streams
│   └─ Node → postgres-pubsub + LISTEN/NOTIFY
├─ Multi-DB federation
│   ├─ Trino / Presto for query
│   └─ Postgres FDW for read federation
├─ Real-time view / materialized stream
│   └─ Materialize, RisingWave, Estuary Flow
├─ Time-series
│   ├─ TimescaleDB (Postgres extension)
│   ├─ InfluxDB v3 (Iox)
│   ├─ ClickHouse (columnar OLAP also great for TS)
│   └─ Prometheus (metrics; not for app data)
├─ Vector / embedding
│   ├─ Pinecone / Weaviate / Qdrant / Milvus (purpose-built)
│   ├─ pgvector + pgvectorscale (Postgres native, simplest)
│   └─ Chroma (lightweight, dev)
├─ Lakehouse / data warehouse
│   ├─ Iceberg + Spark / Trino / Snowflake / Databricks
│   ├─ Delta Lake + Spark
│   └─ DuckDB for in-process analytics
├─ Migrations
│   ├─ Declarative schema-as-code → Atlas
│   ├─ Version-numbered SQL → Flyway, Goose, dbmate
│   ├─ Tied to ORM → Alembic, Prisma Migrate, Drizzle Kit, Diesel, EF Migrations, Rails AR
│   └─ DBA-managed → Liquibase changelogs (XML/YAML/JSON)
└─ CDC / pipelines
     ├─ Debezium + Kafka + Flink (stream)
     ├─ Airbyte / Fivetran (batch ELT)
     ├─ dbt / SQLMesh (warehouse SQL transformations)
     └─ Kafka Connect (universal sinks/sources)

The single biggest practical lesson 2018–2026: the layer that matters is type safety at the schema boundary, not which ORM you picked. The cost of getting a column name wrong in 2026 should be a compile-time error, not a 3 am page. Choose a stack — sqlc + pgx + Atlas (Go); Drizzle + Atlas (TS); SQLAlchemy 2.0 + Alembic (Python); jOOQ + Flyway (JVM); EF Core + EF Migrations (C#) — that surfaces schema diffs as type errors. Heavy runtime ORMs (TypeORM, Sequelize, JPA without jOOQ, GORM, Eloquent) remain fine for simple CRUD, but every team that scales past ~50k lines of data-access logic eventually moves to typed SQL builders + schema codegen. Save the ORM for the CRUD admin; reach for typed SQL at the hot path.