Should I use Bahmni Reports or the OpenMRS Reporting module?

Hi guys!

I have to develop a report that would aggregate some of the patient demographics and few observation data.

Though it seems that the OpenMRS Reporting module would do the job, I am not sure if/why I should use the Bahmni Reports instead. Actually the question is even why is there Bahmni Reports at all? Does it fill some missing features from the OpenMRS Reporting module?

Looking further it seems that Bahmni Reports is a even separate Java application, therefore adding another level of complexity in the Bahmni server. There must be a good reason for this.




Bahmni reports was built for some reasons.

  1. It can connect to multiple databases (openelis and openerp)
  2. It supports specific data constructs created by Bahmni (diagnosis, test results etc) as first class citizens
  3. It emphasises creation of most common reports via json configuration as opposed to writing java/sql code.

Running a different app instead of packaging as an omod helps because

  1. Reports run longer, it might be best for the reporting app to handle its own connections
  2. It is possible to completely run off a slave instance of openmrs, freeing up the master to take care of clinical operations
  3. Deployment complexity is hidden from user because bahmni runs behind an apache proxy.

OpenMRS reporting module is comparatively more flexible and powerful, and consequently, hard to use(in comparison). It might be different if you already have a good idea of how the reporting framework works.

If you are using Bahmni, it makes sense to use bahmni reports - it fits right into the bahmni ui.

Thanks @vinay,

That is quite some advantages indeed.

Thanks @vinay for laying this out.

My sense is that the most significant reason for building out bahmnireports is that it is decoupled from OpenMRS, and so you have more control over the process and limit the impact on the operational JVM from reports that are memory-intensive or long running. And one could presumably choose to just deploy bahmnireports to a reporting server, rather than requiring an OpenMRS instance running there as well.

I take some exception to some of the the functional distinctions listed above.

In Malawi, I recently threw together a SqlFileDataSetDefinition that can point to any SQL resource (either as a String property, a resource on the classpath, or a file on the filesystem), and a connection properties file, and which enables you to execute any SQL code against any data source. So there is no limitation that one needs to connect to the OpenMRS database, or use any existing connections.

One can create DataSetDefinitions, DataDefinitions, ReportDefinitions, etc that can consume and return any data type that one wants. There are a lot of examples out there of modules that create custom data types that support their use cases, and then create reporting definitions that utilize these.

This is more a result in an under-investment in providing out-of-the-box configurable reports via the reporting module than in the capability to do so. I agree that bahmnireports has invested more into this and has more available today that are ready-to-use. But I don’t think this is an inherent advantage of the platform. Said a little differently - if the Bahmni team had decided to, they could have provided the same user-configurable-via-json reports that leveraged the reporting module under the hood.

Just a few cents in defense of the reporting module :slight_smile:


As Mike says, one can use the OpenMRS Reporting module within Bahmni, and this would generally work fine. (Though, you’d need to add a way to run them to the UI.)

If Bahmni Reports provide most of the functionality you need, I’d go with them.

This thread gives a good example of how a hospital that uses Bahmni Reports also leveraged the Reporting Module for a use case it didn’t support: Sending email with summary of daily admissions

Well that seems to be our use case too.

I am focused for now on a MoH requirement to monthly produce a certain report, named ‘Register Logbook’.

This reports will ideally be sent by email at every reporting period, so no need for a UI yet.

Though the data asked has nothing particularly complex, there is a specific requirement on the output format.

For instance for Age:

| Patient ID | 0-28 days | 29 days-11 months | 1-4 years | 5-14 years | 15-24 | 25-49 | 50-64 | _> 65 |

This is not the patient’s Age that we want to display but rather answer ‘Yes’ to the correct age category.

The same is for patient’s gender:

| Man | Women |

I believe this kind of output can not be produced by Bahmni Reports (?)

One last things is that we should be reporting the ‘Weight over Age’ and ‘Weight over Height’ values. Does Bahmni Reports allow to calculate fields?

I think we will use Bahmni Reports to produce other simpler reports, that are more flexible on their output style.

I am very confident in the ability of the OpenMRS Reporting module to produce anything I want. But I haven’t found any developer documentation so the learning curve is steep. I am looking at some modules as example and that’s already very useful, but a little article about how the different elements articulate would be ideal. For instance, looking at the pihmalawi there is a lot of classes to understand: the DataSetDefinition, the DataSetEvaluator, the Converter, the DataDefinition, the DataEvaluator, the Renderer, the Library, the Report…

Any resource I might have missed? (I have watched @mseaton 's screencast and it’s great :thumbsup: , though it shows only the simplest part of the module.)

Where is this information captured? If its in forms it would be stored as Obs. The Observation Report should cater to this. Patient’s gender usually appears by default in most of the reports.

There are 2 options here

  1. Have ‘Weight Over Age’ and ‘Weight Over Height’ as calculated obs like BMI. Whenever weight and height are entered you calculate them through groovy and persist them. Reporting then can happen simply through the out-of-the-box Observation Report
  2. Assuming that these values won’t be just useful for reporting purpose but patient care during consultation as well and so having them as obs and showing them in display control could be desirable. so inclined towards option 1. But If you don’t want them to be stored as obs for whatever reason, you can write a custom SQL report that calculates ‘Height Over Age’ and ‘Weight Over Height’ as part of the query and generates the output.

Regarding the email sending functionality, technically it would be feasible to write a shell script and send emails just by using Bahmni Reports but it would be definitely “more technical” and complex compared to the openmrs reporting as of now because scheduling and sending emails are not first class features of Bahmni reports and that’s why i went ahead with using openmrs reporting for that usecase.

This is not captured as it is anywhere. I just needs it to be populated based on the patient’s age (captured at Registration) when the report is run. The male/female problem is the same. The Male and Female columns should be populated based on patient’s gender… If you see what I mean.

The data is already available, but that’s the output format that is a bit specific. Therefore the data needs to be processed first.

For example:

  • Patient 0010010 is 6 months old
  • Patient 0010017 is 8 years old

The output required is:

| Patient ID | 0-28 days | 29 days-11 months | 1-4 years | 5-14 years | 15-24 | 25-49 | 50-64 | _> 65 |

| 0010010    |           |    true           |           |            |       |       |       |       |
| 0010017    |           |                   |           |    true    |       |       |       |       |

About the calculated observations, I will see with our client if they want to use the Weight/Age and Weight/Height clinically or not. That definitely seems like a good way to go.

About emailing the reports, that’s an acceptable solution to have an external script to send it every so often. Does it mean that Bahmni Reports can schedule reports generation and save them somewhere on the file system?


A few thoughts from your statements above:

Too true. We really need better documentation. I will try to clean up what is there and see if I can make some improvements. Most of it is actually quite straightforward. A definition is evaluated to produce results. Definitions are grouped into types that produce different types of results. CohortDefinitions are evaluated by CohortDefinitionEvaluators to produce Cohorts. PatientDataDefinitions are evaluated by PatientDataEvaluators to produce PatientData. ReportDefinitions are evaluated by ReportDefinitionEvaluators to produce Reports :slight_smile: I agree we need to do a better job of documenting all of these types, what they are used for, and how they fit together.

I know we have done a lot of this outside of the reporting module when needed by simply writing this into SQL queries - either embedded case/if statements, or using functions, etc. @ddesimone may be able to point you to some examples.

I would imagine in this case you would write a shell script that encapsulate both running the report and downloading it from the rest resource and email it out. And then you would set this script to run automatically via crontab. We have used this approach in the past as well, and it works.


1 Like

Yes @mksrom, as @mseaton mentions, we have done this quite a bit in SQL.

See the report below, which is a Haiti MOH report that counts disease episodes by various categories. The series of CASE statements near the bottom sort the rows into gender and age ranges (which are then aggregated in the outer query). You could just as easily return ‘Yes’ or blank in those columns.


Thanks @ddesimone and @mseaton for pointing me to this.

I would really prefer to avoid using SQL to generate the reports. The good thing with SQL query is that it produces the correct result very quickly. Pressured by tight deadlines in the past we have gone this way, but we regret it any time the report is to be changed. I find it very difficult to maintain complicated SQL queries…

My report has more fields than the ones I have detailed above, some of them are just the Chief Complaint, or the Diagnoses for instance.

Could I use a SQL query for only the Age categories part, and build the rest of the report with Java?

@mseaton, about sending emails, thanks for sharing your solution to do this.

@mseaton That would be great! Do you plan to do this soon? I am just asking because I can wait few days for sure, but if it is more, then maybe I could will ask you all my questions on the Talk. :wink:

@mksrom I’d love to say it will happen soon, but I wouldn’t wait. Ask away on talk

Hi all,

I’m very interested in one point that was mentioned at the beginning, but hasn’t cropped up again: if I understand it correctly, Bahmni Reports talks directly to the database, whereas any requests to the OpenMRS reporting module are mediated by an API - is this the case? My understanding is that because it works through an API, the OpenMRS reporting module is quite slow when handling very large and complex reports (lots of processing in Java); does Bahmni reports have the same limitation (ie after doing SQL calls, it then processes data in Java), or does it dynamically form its SQL calls to ensure as much processing as possible is done in the database?

Cheers, Sam.

Bahmni reports do most of their work in SQL, as you can see from the code behind the visit report.

The OpenMRS Reporting module does many things through Java, but it does also allow you to execute direct SQL. So @samueldjohnson I think it’s more complex than just saying that “the OpenMRS reporting module is quite slow”. :slight_smile:

Don’t worry, I didn’t say it was “quite slow” in general - just when handling very large and complex reports (eg aggregating 100,000 patient records). Or have I misunderstood that? (I realise you can write direct SQL queries, but the OpenMRS schema is very complex, so that’s not for everyone.)

However that’s the schema that Bahmni uses anyway, did you notice that leveraging SQL with Bahmni reports was faster than a similar job done through the reporting module then?

I’m ideally looking for reporting options which don’t require SQL, so reports can be developed by M&E / analytical staff (rather than just programmers). Bahmni offers very easy-to-use configurable reports, but the trade-off is that they also seem very limited in what they can do.

Although I haven’t yet started to explore reporting in depth, I’ve had to get my head around the OpenMRS schema in order to develop patient lists in Bahmni, and the nesting of observations etc means this requires more complex SQL than most other systems I’ve used. But do most projects ultimately end up resorting to reporting options which require direct SQL queries?