You are here

Doctrine or Propel for your database access code?

Submitted by Peter on Tue, 2011-09-06 18:38

Can you improve your database access code using Doctrine, Propel, or some other database access library? Doctrine and Propel are the best known varieties of software called ORM or Object Relational Mapping. ORM can make some things easier but it is not magic. You need to know what ORM does well and what it does not do.

Both Propel and Doctrine have more similarities than differences. You can study the use of either product to find out the advantages and disadvantages of ORM. There are many other ORM options but none of the others do anywhere near as much as Doctrine and Propel. Propel is described at www.propelorm.org and Doctrine at www.doctrine-project.org.

Will ORM make development faster? Your first use of ORM will not make development faster and may make development slower. You might save some time later when you are adding extra features to an existing application built using ORM.

Will ORM make development easier? The first time you use ORM, development will be more difficult while you learn how to use ORM. Doctrine has, in the past, had better documentation than Propel but learning how to use Doctrine was still difficult. There are many extra steps required to set things up initially. You have to work on an application for a while to regain the setup time. ORM can make life easier when you want to share a database design with several applications.

Will ORM make development more reliable? ORM has a real advantage when you want to share a database with several applications. You change your design once then ship the design to the other applications. Forget the problems of trying to recreate a database change in several applications.

Why use either ORM? ORM has an advantage when using complicated databases in several applications. Doctrine and Propel will do everything that you can currently do with ORM. No other ORM will give you as many advantages. If you can make use of ORM, you will use one of these ORM products. There is little point in using something less capable. The current decision is really to use one of these two ORM products or to not use ORM.

Which is better, Propel or Doctrine? The current releases of both products are close. Doctrine is faster to learn and Propel is faster to execute. Both are catching up with the other in areas where they were weak. You might have a personal preference for one based on one feature then find the other has that feature next year.

I find some Doctrine code easier to read than the equivalent Propel code but the code generated by Propel is better than the code generated by Doctrine. Native code with plain SQL is often just as easy to write and read.

The performance advantage of Propel over Doctrine is enough to make me choose Propel over Doctrine for projects running on my computer. The performance advantage of native code over both Propel and Doctrine makes me choose native code ahead of both ORM products. Code frameworks, including the Drupal CMS, save far more time than either ORM product.

Documentation

A lot of people recommend Doctine over Propel for documentation. I find some parts of Doctrine slightly easier to read but not enough to choose Doctrine based on the readability of code examples or documentation.

The last time I made a serious attempt to use Doctrine and Propel side by side was in an evaluation of Symfony for a big project. Both Symfony and Doctrine were part way through a big rewrite to version 2. The documentation for the old version was extensive but there were reasons why the old version of Symfony would not be chosen for the project and the new version was still to far away. Looking at Symfony today, Symfony with either Propel or Doctrine would be a better fit for the project but would still be down at the second or third choice, not the first choice.

The Zend framework is another contender using either Doctrine or Propel. The Zend Framework is in the middle of a big rewrite that promises serious improvements in some areas but also brings unnecessary complexity and resource wastage in other areas. You might save some time using Propel or Doctrine with Zend Framework. You will then lose the savings learning all the new stuff in the Zend framework.

In almost every case, switching to a different technology does not save time on one project because of the steep learning curve. You really need more than good documentation, you need examples very close to what you want to do. The introductory pages for both Propel and Doctrine show examples too simple to save me time, compared to hand coding, and there appears to be too much reading to get through to the point where I could solve the complex problems causing the biggest delays in the development of database based applications.

You might save time on subsequent projects if you can reuse designs and code. An example is a developer working on a series of Web sites for shops. The sites might look completely different but the structure of product details, shopping carts, and many other components will remain the same.

Performance

Every test of Doctrine versus Propel shows Propel is faster and the only argument is how fast. There are odd bits of Propel that are as slow as Doctrine and odd bits of Doctrine that are fast enough to be practical. If performance is your highest priority, hand built code is faster than either Propel or Doctrine. As a rough guide based on common application usage, Propel is twice as fast as Doctrine and hand built code is twice as fast as Propel.

Doctrine version 2 is faster than the older versions of Doctrine and there is a distinct lack of documented comparisons to help you get the best performance out of Doctrine 2 or to evaluate the overhead cost for Doctrine when you are looking at replacing existing code with Doctrine based code.

Propel has improved from release to release but not by a big amount and last year's benchmarks for Propel remain current. Propel does have some new alternatives for specifying queries and they may be faster but there are no published benchmarks.

Terminology

Here is some terminology you have to learn to keep up with ORM.

Hydration

Hydration is one of the stupid terms you have to learn when using ORM. Hydration refers to adding data to objects but has a number of conflicting uses that make hydration almost useless as a term. If you write your own native code to access data, you will learn what works then you can try to work backwards to what the ORM products do with your requests. You then find that hydration describes only the result, not the technique, and some of the techniques used in ORM software are truly primitive.

The big problem with ORM is the case where an object is built with data from several tables. How is the object built? Is the whole objected filled with data? Is the data retrieved in one request or many requests?

You might need an object for only one attribute value. The ORM software might fill/populate/hydrate the object with data from several tables, wasting huge resources, when you need only one value from the first bit of data. You have to work your way around your ORM to find out how to retrieve only what you need.

Your object might use data from several tables that can be joined to return all the data from one request. Your ORM might decide to generate several requests because ORM is not good at joining tables. Doctrine and Propel are improving but may not make the right choice for your use.

Your object might need one row from one table and several rows from another table. Think of an invoice object containing several line item rows. Your ORM might build the object the same way you would if you coded the SQL requests by hand. Now use the same object to get just the invoice total. Will your ORM optimise the object to not read the line item rows when they are not needed? This is where you have to understand all the different ways ORM software can hydrate an object.

Your next step, for frequently used queries, is to spend a lot of time learning how to twist ORM access requests so they work efficiently, so they work the way you you would write the request if you were not forced to use ORM. Investigate the new features of the latest releases. Consider building non ORM requests for frequently used database accesses.

YAML

You might hear about YAML. YAML is a language for writing database definitions. YAML is just a distraction. YAML makes simple database definitions look simple. Complex databases look horrible when described using YAML. YAML breaks most of the good design rules you apply when designing a database or creating an application.

Frameworks

You can save application development time by using an application development framework. Some frameworks include an ORM product. You save more time using ORM with an ORM oriented framework than you save using ORM by itself.

The Symfony framework is popular and is usually used with Doctrine. You can also use Propel with Symfony but the Symfony developers push Doctrine. The Zend Framework is also popular and works with either ORM. If you want a choice of ORM, look for a framework that works with the ORM you want to use. In most cases you are better off choosing the best framework for your task then use the ORM provided with the framework because the framework will save you more time than the ORM.

Content management systems

For Web sites, a good CMS, a Content Management System, will save you more time than a framework or an ORM. If the CMS happens to use an ORM, that might help you expand the CMS to fit your requirements. Most CMS products have a database application layer but not ORM because the overheads of a CMS are already high and adding an ORM could kill the CMS.

The Drupal database abstraction layer as a comparison

Drupal has a database abstraction layer somewhere in between the PHP PDO code and Doctrine. There are similarities across the three because they use similar methods for building query objects. I could understand someone moving from Drupal to Doctrine. The original Propel query building would look backwards compared to Drupal and Doctrine. Propel now has something similar and might make the migration easier.

The current documentation for the new version of Drupal reminds me of the Doctrine documentation. There is a lot of documentation. A lot of the documentation is of high quality but is disjointed and lacks examples relevant to the problems causing the most pain. If you could combine the best of the work on Drupal and the best of the work on doctrine, the result would be strong and flexible.

Today I battled with a resource decision. I could write something to work fast but use a massive amount of memory or I could write the code to reduce memory usage by using a slower processing approach. The Drupal functions gave me a choice but not a good choice and finding the alternatives was painful. I had similar problems the last time I tried to find examples in Symfony with either Doctrine or Propel.

Both Propel and Doctrine talk about caching requests and Drupal has something similar. Both Doctrine and Propel offer alternative ways to add data to objects, hydration in their language, and Drupal does offer similar choices. The problem with Drupal is the combination of cache and hydration wasting masses of memory in situations where you do not need most of the data. Users report the same type of problem with both Propel and Doctrine. You have to be really careful how to handle large chunks of data and long lists of small data items.

There are people who know how to get the best out of the various products. There are large active Web sites built using various combinations of the different technologies. There are also a lot of serious problems ready to trap new users. I suggest you choose technology with an active friendly user community, something Drupal has in many countries.

I have not tried to get support from either the Doctrine or the propel user community. If I use either product for future projects, it will be within a framework. I will look for a framework with a strong user community and will probably use the most popular ORM option for that framework. If Drupal switches to a separate ORM, instead of continuing developing of their current approach, I prefer the performance of Propel coupled with the recent interface enhancements that make Propel coding similar to the best parts of Doctrine.

A bigger jump for Drupal would be to adopt Symfony as a framework and, in that case, Doctrine would win over Propel because it is easier to find experienced Symfony developers using the latest version of Doctrine.

There are other frameworks out there offering some shortcuts for content management system development and, in most cases, the frameworks offer more advantages that minor differences between Propel and Doctrine. Choose the framework then use the ORM recommended for the framework.

Conclusion

ORM can save you time if you spend a lot of time designing and building the database part of applications. In most other situations the overheads of learning ORM are greater than the benefits unless someone is feeding you predesigned databases you can plug in instantly using ORM.