9 comments

  • jgauth 0 minutes ago
    [delayed]
  • roel_v 1 hour ago
    Why would one want to couple these two? Doesn't that couple, say, your API interface with your database schema? Whereas in reality these are separate concepts, even if, yes, sometimes you return a 'user' from an API that looks the same as the 'user' in the database? Honest question, I only just recently got into FastAPI and I was a bit confused at first that yes, it seemed like a lot of duplication, but after a little bit of experience, they are different things that aren't always the same. So what am I missing?
    • whinvik 10 minutes ago
      Yeah I have always struggled to figure out why I would use SQLModel.

      Big fan of FastAPI but I think SQLModel leads to the wrong mental model that somehow db model and api schema are the same.

      Therefore I insist on using SQLAlchemy for db models and pydantic for api schemas as a mental boundary.

    • mr_Fatalyst 1 hour ago
      The ORM doesn't force you to use the DB model as your API schema. It's a regular Pydantic BaseModel, so you can make separate request/response schemas whenever you need to. For simple CRUD, using the model directly saves boilerplate. For complex cases, you decouple them as usual. The goal is not one model for everything, it's one contract. Everything speaks Pydantic, whether it's your API layer or your database layer.
  • throwawayffffas 3 days ago
    Lol I never knew django orm is faster than SQLAlchemy. But having used both that makes sense.

    > Why Rust? ... Rust handles the database plumbing. Queries are built as an IR in Python, serialized via MessagePack, sent to Rust which generates dialect-specific SQL, executes it, and streams results back. Speed is a side effect of this split, not the goal.

    Nice.

    So what does it take to deploy this, dependency wise?

    • kstrauser 1 hour ago
      > Lol I never knew django orm is faster than SQLAlchemy.

      I don’t believe that for a second. Both are wonderful projects, but raw performance was never one of Django ORM’s selling points.

      I think its real advantage is making it easy to model new projects and make efficient CRUD calls on those tables. Alchemy’s strong point is “here’s an existing database; let users who grok DB theory query it as efficiently and ergonomically as possible.”

      • mr_Fatalyst 1 hour ago
        I was surprised too when I saw the results. The benchmarks test standard ORM usage patterns, not the full power of any ORM. SQLAlchemy is more flexible, but that flexibility comes with some overhead. That said, the ORM layer is rarely the bottleneck when working with a database. The benchmarks were more about making sure that all the Pydantic validation I added comes for free, not about winning a speed race.
    • mr_Fatalyst 3 days ago
      Just pip install oxyde, that's it. The Rust core (oxyde-core) ships as pre-built wheels for Linux, macOS, and Windows, so no Rust toolchain needed. Python-side dependencies are just pydantic, msgpack, and typer for the CLI. Database drivers are bundled in the Rust core (uses sqlx under the hood), so you don't need to install asyncpg/aiosqlite/etc separately either.
  • knrz 49 minutes ago
    Lowkey hope this replaces Django ORM
    • mr_Fatalyst 46 minutes ago
      Thanks! Not really trying to replace Django ORM though, it's great at what it does. Just trying to build the ORM I'd personally want to use in 2026.
  • ForHackernews 1 hour ago
    This sounds great and there's a real gap in the ecosystem for a tool like this. https://sqlmodel.tiangolo.com/ looked promising but it's actually worse than useless because if you add it to your Pydantic models, it disables all validation: https://github.com/fastapi/sqlmodel/issues/52
    • mr_Fatalyst 1 hour ago
      Thanks! Yeah, that SQLModel issue is actually one of the things that pushed me to build this. In Oxyde the models are just Pydantic BaseModel subclasses, so validation always works, both on the way in and on the way out via model_validate().
  • waterTanuki 39 minutes ago
    We need more creative names for rust packages because this is going to cause confusion

    There's already Oxide computers https://oxide.computer/ and Oxc the JS linter/formatter https://oxc.rs/.

    • mr_Fatalyst 35 minutes ago
      Yeah, we're running out of ways to spell oxide (^_^)
  • TZubiri 57 minutes ago
    Didn't the committee agree that ORMs were a mistale and a thing of the past?
    • mr_Fatalyst 49 minutes ago
      Must have missed that meeting. ORMs are not for everything, but for CRUD-heavy apps with validation they save a lot of boilerplate. And there's always execute_raw() for when you need to go off-script.
    • zamalek 35 minutes ago
      Micro-orms (mapping to parameters and from columns) are generally fine last i read. It is the general aversion to writing a SELECT that is suspect.
  • instig007 58 minutes ago
    > But infrastructure stuff like SQL generation, connection pooling, and row serialization is where a systems language makes sense.

    not really, what makes sense is being JIT-able and friendly to PyPy.

    > Type safety was a big motivation.

    > https://oxyde.fatalyst.dev/latest/guide/expressions/#basic-u...

    > F("views") + 1

    If your typed query sub-language can't avoid stringly references to the field names already defined by the schema objects, then it's the lost battle already.

    • mr_Fatalyst 51 minutes ago
      The Rust core is not just about speed. It bundles native database drivers (sqlx), connection pooling, streaming serialization. It's more about the full IO stack than just making Python faster. On F("views"), fair point. It's a conscious trade-off for now. The .pyi stubs cover filter(), create(), and other query methods, but F() is still stringly-typed. Room for improvement there.
      • instig007 24 minutes ago
        > It's more about the full IO stack than just making Python faster.

        Does it mean that your db adapter isn't necessarily DBAPI (PEP-249) compliant? That is, it could be that DBAPI exception hierarchy isn't respected, so that middlewares that expect to work across the stack and catch all DB-related issues, may not work if the underlying DB access stack is using your drivers?

        > but F() is still stringly-typed. Room for improvement there.

        Yeah, I'm pretty sure F() isn't needed. You can look at how sqlalchemy implements combinator-style API around field attributes:

            import sqlalchemy as sa
            from sqlalchemy.orm import DeclarativeBase
        
        
            class Base(sa.orm.DeclarativeBase):
                pass
        
            class Stats(Base):
                __tablename__ = "stats"
        
                id = sa.Column(sa.Integer, primary_key=True)
                views = sa.Column(sa.Integer, nullable=False)
        
            print(Stats.views + 1)
        
        The expression `Stats.views + 1` is self-contained, and can be re-used across queries. `Stats.views` is a smart object (https://docs.sqlalchemy.org/en/21/orm/internals.html#sqlalch...) with overloaded operators that make it re-usable in different contexts, such as result getters and query builders.
        • mr_Fatalyst 16 minutes ago
          Right, it's not DBAPI compliant. The whole IO stack goes through Rust/sqlx, so PEP-249 doesn't apply. Oxyde has its own exception hierarchy (OxydeError, IntegrityError, NotFoundError, etc.). In practice most people catch ORM-level exceptions rather than DBAPI ones, but fair to call out.

          On F(), good point. The descriptor approach is something I've been thinking about. Definitely on the radar.

  • catlover76 0 minutes ago
    [dead]