ORM Compatibility
ParticleDB implements the PostgreSQL wire protocol, so most ORMs and query builders that support PostgreSQL work with no changes. Point the connection string at ParticleDB and go.
Compatibility Matrix
Section titled “Compatibility Matrix”| ORM / Framework | Language | Connection String | Status |
|---|---|---|---|
| SQLAlchemy | Python | postgresql://localhost:5432/main | Tested |
| Django ORM | Python | See below | Tested |
| Prisma | TypeScript | postgresql://localhost:5432/main | Tested |
| Drizzle ORM | TypeScript | postgresql://localhost:5432/main | Tested |
| TypeORM | TypeScript | postgresql://localhost:5432/main | Tested |
| GORM | Go | host=localhost port=5432 dbname=main | Tested |
| Diesel | Rust | postgresql://localhost:5432/main | Tested |
| Hibernate / JPA | Java | jdbc:postgresql://localhost:5432/main | Tested |
| JOOQ | Java | jdbc:postgresql://localhost:5432/main | Tested |
| Entity Framework Core | C# / .NET | Host=localhost;Port=5432;Database=main | Tested |
| Dapper | C# / .NET | Host=localhost;Port=5432;Database=main | Tested |
SQLAlchemy (Python)
Section titled “SQLAlchemy (Python)”pip install sqlalchemy psycopg2-binaryfrom sqlalchemy import create_engine, Column, BigInteger, String, Floatfrom sqlalchemy.orm import declarative_base, Session
engine = create_engine("postgresql://localhost:5432/main")Base = declarative_base()
class Product(Base): __tablename__ = "products" id = Column(BigInteger, primary_key=True) name = Column(String, nullable=False) price = Column(Float)
# Create tablesBase.metadata.create_all(engine)
# Insertwith Session(engine) as session: session.add(Product(id=1, name="Wireless Mouse", price=29.99)) session.commit()
# Querywith Session(engine) as session: products = session.query(Product).filter(Product.price > 20).all() for p in products: print(f"{p.name}: ${p.price:.2f}")Async SQLAlchemy
Section titled “Async SQLAlchemy”from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
# Use asyncpg as the async driverengine = create_async_engine("postgresql+asyncpg://localhost:5432/main")
async with AsyncSession(engine) as session: result = await session.execute(select(Product).where(Product.price > 20)) for p in result.scalars(): print(f"{p.name}: ${p.price:.2f}")Django ORM (Python)
Section titled “Django ORM (Python)”In settings.py:
DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", "NAME": "main", "HOST": "localhost", "PORT": "5432", }}from django.db import models
class Product(models.Model): name = models.CharField(max_length=255) price = models.FloatField()
class Meta: db_table = "products"
# UsageProduct.objects.create(name="Wireless Mouse", price=29.99)expensive = Product.objects.filter(price__gt=50).order_by("-price")Prisma (TypeScript)
Section titled “Prisma (TypeScript)”In schema.prisma:
datasource db { provider = "postgresql" url = "postgresql://localhost:5432/main"}
generator client { provider = "prisma-client-js"}
model Product { id BigInt @id name String price Float?}import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
// Insertawait prisma.product.create({ data: { id: 1n, name: "Wireless Mouse", price: 29.99 },});
// Queryconst expensive = await prisma.product.findMany({ where: { price: { gt: 50 } }, orderBy: { price: "desc" },});
console.log(expensive);Drizzle ORM (TypeScript)
Section titled “Drizzle ORM (TypeScript)”npm install drizzle-orm pgnpm install -D drizzle-kit @types/pgimport { drizzle } from "drizzle-orm/node-postgres";import { pgTable, bigint, varchar, doublePrecision } from "drizzle-orm/pg-core";import { gt } from "drizzle-orm";import { Client } from "pg";
const products = pgTable("products", { id: bigint("id", { mode: "number" }).primaryKey(), name: varchar("name").notNull(), price: doublePrecision("price"),});
const client = new Client("postgresql://localhost:5432/main");await client.connect();const db = drizzle(client);
// Insertawait db.insert(products).values({ id: 1, name: "Wireless Mouse", price: 29.99 });
// Queryconst expensive = await db.select().from(products).where(gt(products.price, 50));console.log(expensive);TypeORM (TypeScript)
Section titled “TypeORM (TypeScript)”npm install typeorm pg reflect-metadataimport { DataSource, Entity, PrimaryColumn, Column } from "typeorm";import "reflect-metadata";
@Entity("products")class Product { @PrimaryColumn("bigint") id: number;
@Column("varchar") name: string;
@Column("double precision", { nullable: true }) price: number;}
const ds = new DataSource({ type: "postgres", host: "localhost", port: 5432, database: "main", entities: [Product], synchronize: true,});
await ds.initialize();
const repo = ds.getRepository(Product);
// Insertawait repo.save({ id: 1, name: "Wireless Mouse", price: 29.99 });
// Queryconst expensive = await repo.find({ where: { price: MoreThan(50) }, order: { price: "DESC" },});GORM (Go)
Section titled “GORM (Go)”go get gorm.io/gormgo get gorm.io/driver/postgrespackage main
import ( "fmt" "log"
"gorm.io/driver/postgres" "gorm.io/gorm")
type Product struct { ID int64 `gorm:"primaryKey"` Name string `gorm:"not null"` Price float64}
func main() { dsn := "host=localhost port=5432 dbname=main sslmode=disable" db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) if err != nil { log.Fatal(err) }
// Auto-migrate db.AutoMigrate(&Product{})
// Insert db.Create(&Product{ID: 1, Name: "Wireless Mouse", Price: 29.99})
// Query var products []Product db.Where("price > ?", 50).Order("price desc").Find(&products) for _, p := range products { fmt.Printf("%s: $%.2f\n", p.Name, p.Price) }}Diesel (Rust)
Section titled “Diesel (Rust)”cargo add diesel --features postgrescargo install diesel_cli --no-default-features --features postgres// schema.rs (generated by diesel CLI)diesel::table! { products (id) { id -> Int8, name -> Varchar, price -> Nullable<Float8>, }}
// models.rsuse diesel::prelude::*;
#[derive(Queryable, Selectable)]#[diesel(table_name = products)]struct Product { id: i64, name: String, price: Option<f64>,}
#[derive(Insertable)]#[diesel(table_name = products)]struct NewProduct<'a> { id: i64, name: &'a str, price: Option<f64>,}
// main.rsuse diesel::prelude::*;use diesel::pg::PgConnection;
fn main() { let database_url = "postgresql://localhost:5432/main"; let mut conn = PgConnection::establish(database_url) .expect("Error connecting to ParticleDB");
// Insert diesel::insert_into(products::table) .values(&NewProduct { id: 1, name: "Wireless Mouse", price: Some(29.99) }) .execute(&mut conn) .expect("Error inserting");
// Query let results = products::table .filter(products::price.gt(50.0)) .order(products::price.desc()) .load::<Product>(&mut conn) .expect("Error querying");
for p in results { println!("{}: ${:.2}", p.name, p.price.unwrap_or(0.0)); }}The DATABASE_URL for Diesel CLI:
echo "DATABASE_URL=postgresql://localhost:5432/main" > .envdiesel setupdiesel migration generate create_productsHibernate / JPA (Java)
Section titled “Hibernate / JPA (Java)”In persistence.xml:
<persistence-unit name="particledb"> <properties> <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/main"/> <property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver"/> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/> <property name="hibernate.hbm2ddl.auto" value="update"/> </properties></persistence-unit>@Entity@Table(name = "products")public class Product { @Id private Long id; private String name; private Double price;
// getters, setters}
// UsageEntityManagerFactory emf = Persistence.createEntityManagerFactory("particledb");EntityManager em = emf.createEntityManager();
em.getTransaction().begin();em.persist(new Product(1L, "Wireless Mouse", 29.99));em.getTransaction().commit();
List<Product> expensive = em.createQuery( "SELECT p FROM Product p WHERE p.price > :price ORDER BY p.price DESC", Product.class).setParameter("price", 50.0).getResultList();Entity Framework Core (C# / .NET)
Section titled “Entity Framework Core (C# / .NET)”dotnet add package Npgsql.EntityFrameworkCore.PostgreSQLusing Microsoft.EntityFrameworkCore;
public class AppDbContext : DbContext{ public DbSet<Product> Products => Set<Product>();
protected override void OnConfiguring(DbContextOptionsBuilder options) { options.UseNpgsql("Host=localhost;Port=5432;Database=main"); }}
public class Product{ public long Id { get; set; } public string Name { get; set; } = ""; public double? Price { get; set; }}
// Usageawait using var db = new AppDbContext();
// Insertdb.Products.Add(new Product { Id = 1, Name = "Wireless Mouse", Price = 29.99 });await db.SaveChangesAsync();
// Queryvar expensive = await db.Products .Where(p => p.Price > 50) .OrderByDescending(p => p.Price) .ToListAsync();
foreach (var p in expensive){ Console.WriteLine($"{p.Name}: ${p.Price:F2}");}Connection String Reference
Section titled “Connection String Reference”All ORMs use standard PostgreSQL connection strings. Here is the format for each:
| ORM | Format | Example |
|---|---|---|
| SQLAlchemy | postgresql://host:port/db | postgresql://localhost:5432/main |
| Django | Dict in settings.py | See Django section above |
| Prisma | postgresql://host:port/db | postgresql://localhost:5432/main |
| Drizzle | postgresql://host:port/db | postgresql://localhost:5432/main |
| TypeORM | Separate fields or URL | host: "localhost", port: 5432 |
| GORM | DSN string | host=localhost port=5432 dbname=main |
| Diesel | postgresql://host:port/db | postgresql://localhost:5432/main |
| Hibernate | JDBC URL | jdbc:postgresql://localhost:5432/main |
| EF Core | Npgsql string | Host=localhost;Port=5432;Database=main |
Known Limitations
Section titled “Known Limitations”Most PostgreSQL ORMs work seamlessly. A few features that rely on PostgreSQL-specific internals may have limited support:
- Schema migrations that use
pg_catalogintrospection queries may need adjustments - Advisory locks used by some migration tools are not yet supported
- Sequences (auto-increment) work via
BIGINT PRIMARY KEYwith application-generated IDs - ENUM types are not yet supported; use
VARCHARwith application-level validation
If you encounter compatibility issues with a specific ORM, please report them — we continually expand protocol coverage.
Next Steps
Section titled “Next Steps”- PostgreSQL Wire Protocol — Protocol-level compatibility details
- SQL Reference — Supported SQL syntax
- SDKs — Language-specific guides