28 Jan 2009

Elixir’s vision

Posted by ged

Here is a post I have started to write a long time ago but always postponed its completion…

Reading Elixir’s mailing list and some comments about Elixir on various blogs, I came to realize that many people don’t get what the real goal of Elixir is. To be honest, I didn’t realize it myself until a couple months ago.

Sure, it abstracts some of the little details, but this has never been a goal in itself and is only a consequence of the goal. The initial goal was only to provide a declarative syntax. This goal is now also filled by the SQLAlchemy built-in declarative extension.

But what differentiate Elixir from declarative is its ability to generate columns (and other structures) and thus save people from repetitive declarations, both by providing built-in constructs for common patterns as well as providing a way to define their own patterns. For example, if you declare a many-to-one relation between a source entity and a target entity, you nearly always want to add a column in the source entity table with a foreign key constraint to the primary key column of the target entity table. When using pure SQLAlchemy, you have to declare the relationship and the column separately as in:

class Address(Base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    email_address = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'))
    user = relation(User, backref=backref('addresses', order_by=id))

while in Elixir, this is done in one step, as in:

class Address(Entity):
    email_address = Field(String, required=True)
    user = ManyToOne('User')

So, yes, Elixir generates columns for you, but it is not (and never was) meant to hide them from you. It is just meant to save you the trouble to explicitly declare them over and over again. In short, Elixir is a sort of templating system for SQLAlchemy, but to best benefit from Elixir, you should know what it generates for you, and thus you should understand how “raw SQLAlchemy” works.

Ok, now that I said that I hear people coming with the complaint that in our documentation we don’t explain clearly nor prominently what gets generated for all constructs. You would be right. I wonder why nobody ever complained about this… For what it’s worth, I consider those issues bugs and I am committed to fix them in time. Of course, I would gladly accept patches adding such documentation.

As to better clarify my “vision” of Elixir’s future, here are the “abstract” goals I have for Elixir:

  • Implement more useful patterns,
  • provide ways to customize all the provided patterns the exact way you want them,
  • and do not get in the way when you do not want to use them at all.

The only limitation Elixir should add is the inherent declarative limitation, which is that you can’t map the same class to different tables/selectables.

Incidentally, these are roughly the release criteria for Elixir 1.0, whenever that will happen.

Leave a Reply