As indicated by #983438: Don't allow batched export on PostgreSQL, this module doesn't support postgreSQL databases due to database query incompatibilities. As I use postgreSQL as a backend and can't change to MySQL for various reasons, I proposed that support for PostgreSQL be added to this module. I'm quite familiar with postgreSQL and thus intend to start working on a patch... I intend to keep a log of my progress here and would appreciate any help that like-wise minded developers would like to provide.

A note to the maintainers: If you could point out the places that postgreSQL incompatibilities exist that would greatly aid my efforts!

Comments

laceysanderson’s picture

Just finished confirming that the non-batched export works on postgreSQL. I was able to export both csv and xls of 8,000 lines + with no problem. However, a batched export would be ideal for these situations.

Progress on Batched Export:
I had hoped that this would be as simple as adding an if statement that would use CREATE TABLE {tablename} AS... instead of CREATE TABLE {tablename} SELECT... when the database driver is pgsql. However, even after making that change, I still get a number of errors and an empty file (except for header). Next it is complaining about the @row := @row + 1 AS vde_weight bit of the statement... However, I have never seen such notation before (being completely unfamiliar with MySQL).

If anyone can explain this notation to me so that I can determine a postgreSQL equivalent it would help a Lot!

~Lacey

laceysanderson’s picture

Okay, I've fixed the problem :) That said, I don't use git and can't seem to even clone this project let alone create a patch for it *Sighs!*

I'm using Debian 6.0; Git 1.7.2.5
I'm trying to run git clone --branch 6.x-2.0-beta5 http://git.drupal.org/project/views_data_export.git but I get an empty directory... Any idea what I'm doing wrong?

Anyway, Changes that need to be made: in plugins/views_data_export_plugin_display_export.inc Line 547 gets changed to

if ($this->_get_database_driver() == 'pgsql') {
  // Create temporary sequence
  $seq_name = $this->index_tablename() . '_seq';
  $create_seq_query = 'CREATE TEMP sequence ' . $seq_name;
  // query uses sequence to create row number
  $insert_query = 'CREATE TABLE {' . $this->index_tablename() . "} AS SELECT nextval('".$seq_name."') AS " . $this->batched_execution_state->sandbox['weight_field_alias'] . ', ' . implode(', ', $select_aliases) . ' FROM (' . $query . ') AS cl';
} else {
  // Original insert query remains unchanged
  $insert_query = 'CREATE TABLE {' . $this->index_tablename() . '} SELECT @row := @row + 1 AS ' . $this->batched_execution_state->sandbox['weight_field_alias'] . ', ' . implode(', ', $select_aliases) . ' FROM (' . $query . ') AS cl, (SELECT @row := 0) AS r';
}

The following is added directly above Line 555

      if ($this->_get_database_driver() == 'pgsql') {
        db_query($create_seq_query);
      }

And the incompatible pgsql driver gets removed from the array at Line 781.

laceysanderson’s picture

Status: Active » Needs review
StatusFileSize
new2.24 KB

Figured it out! git clone --branch 6.x-2.x http://git.drupal.org/project/views_data_export.git

Anyway I've attached a patch.

Testing:
This patch was tested on a Drupal 6.22 site with a postgresql 8.4.7 backend. First I needed a node view to test it on. I enabled the default frontpage view and changed the style of the Default display to table. I also added the title, teaser, post date and type fields. The view worked properly. I then added a Data Display of style csv with batched export set to yes. I also attached the data export display to the page display. When I click on the csv link on the frontpage page, I was brought to a progress bar which completely within 3 minutes and presented me with a csv file with 34,783 lines which corresponded to the number of rows in my view :) There were no errors displayed during this process. The index table was created properly.

As for justification of my changes:
Since the problem was the CREATE TABLE {tablename} SELECT ... which was causing problems for postgresql backends, I added an if statement to use a postgresql specific query if the driver used was pgsql and otherwise to use the original insert query. The postgresql specific query uses the postgresql specific CREATE TABLE {tablename} AS SELECT ....

Another postgresql incompatible piece of the query was the @row := @row + 1 which I interpreted to add a sequential row number to the table. The recommended way to do this in postgresql (compatible with earlier versions, easy to understand and read, better performance: see http://www.postgresonline.com/journal/archives/79-Simulating-Row-Number-...) is by creating a temporary sequence (will be dropped at end of session) and using that to create the row number -hence the next_val('sequencename'). I used the name of the table concatenated to _seq in order to ensure that the temporary sequence was unique and would not cause collisions.

ben coleman’s picture

I need this, but I need it in 7.x-3.x. I'll try to set up a Drupal 6 site here to review this. Think it will be hard to port this to 7.x-3.x?

ben coleman’s picture

Title: PostgreSQL support » PostgreSQL support for batched export
Status: Needs review » Reviewed & tested by the community

I'll confirm this works for both PostgreSQL and MySQL (i.e. it works for PostgreSQL, and doesn't break MySQL). I ran tests on both, outputting the same view both as batched, and as non-batched. For both, the batched and non-batched output was identical. Looks good to me.

I'm going to take this patch and see if the same kind of thing can be done for 7.x-3.x. Will post to a separate issue.

christine1126x’s picture

Thanks laceysanderson,

Patch works perfectly :)

steven jones’s picture

Status: Reviewed & tested by the community » Fixed

Huge thanks for the patch and reviews, I've incldued this in 6.x-2.x and 7.x-3.x.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.