ormai vs raw SQLAlchemy for AI agents: policy-enforced database access
ormai wraps SQLAlchemy, Tortoise, Peewee, Django, SQLModel (Python) and Prisma, Drizzle, TypeORM (TypeScript) in a policy-enforced runtime. Field-level redaction, query budgets, tenant scoping, immutable audit logs.
$ pip install ormai ormai is a Rust-backed drop-in for
SQLAlchemy (raw). Same API, faster hot paths.
Install: pip install ormai.
Policy engine: field-level redaction, hashing, masking built in.
ormai vs SQLAlchemy (raw): the facts
Policy engine: field-level redaction, hashing, masking built in.
No built-in policy; you write guards in your agent.
Query budgets (per-agent, per-tenant).
Manual rate-limiting in app code.
Automatic tenant scoping (multi-tenant safe).
You write the WHERE clauses; agent can forget.
Immutable audit log of every operation.
Add your own audit layer (or skip it).
No raw SQL exposed to the model.
The agent can issue `session.execute(text(...))`.
Same SQLAlchemy models — wrap, don't migrate.
Direct SQLAlchemy.
MIT licensed.
MIT licensed.
When to use ormai
- You give an AI agent database access and need to be able to say "the model physically cannot read PII columns".
- You run a multi-tenant SaaS and need tenant scoping that doesn't depend on the agent remembering.
- You need a queryable audit log of what the agent did.
When NOT to use ormai
- The agent never touches the database.
- You are fine with prompt-engineered "you must not read the PII columns" controls.
Frequently asked questions
Does ormai replace SQLAlchemy?
No — ormai wraps your existing SQLAlchemy models. You keep the same `class User(Base)` definitions; ormai adds the policy runtime on top.
Does ormai work with my ORM?
Python: SQLAlchemy, Tortoise, Peewee, Django, SQLModel. TypeScript: Prisma, Drizzle, TypeORM.
What does "field-level redaction" actually mean?
You declare a policy: `redact(User.email, "hash")`. ormai then ensures that any read of `User.email` returns a hashed value, regardless of how the agent queries. The agent can never see the raw email even if it asks for it explicitly.