[Bioperl-l] PostgreSQL & lookup & insert in bioperl-db

Hilmar Lapp hlapp at gnf.org
Wed Feb 26 18:25:21 EST 2003


This is a problem I stated a couple of months ago and that has 
basically remained unsolved. I try here to summarize it again, and I'll 
point out 3 alternatives I see for solving the problem. Each of those 
alternatives has different advantages and disadvantages. I'd like to 
get a community vote on what the best and/or most preferred solution 
would be. If you're using bioperl on biosql or plan doing so, please 
read and vote if you have an opinion (some of the alternatives would 
affect all RDBMSs, not just Pg). Otherwise ignore ...

Here's the background.

The current code in the bioperl-db adaptors to biosql run the 
connection with AutoCommit off, which means the client determines the 
transaction. Load_seqdatabase.pl (the main script for loading databases 
into biosql) treats one sequence entry as one transaction. If any sql 
statement required for loading the sequence fails unexpectedly, the 
whole transaction is rolled back, otherwise it is committed once the 
entry and all its annotation went in successfully. The emphasis rests 
on 'unexpectedly': INSERTs may fail due to unique key violations, which 
is caught and triggers a look-up of the affected entry by unique key. 
E.g. a dbxref may already exist; if so, it needs to be looked up in 
order to establish the association with the bioentry.

Here's the problem.

If within a transaction a particular statement fails, in Oracle and 
MySQL/InnoDB only that particular statement fails, not the previous 
ones in the same transaction, nor the subsequent ones. If you commit 
the transaction, all the succeeded statements' results get committed. 
In PostgreSQL, however, the entire transaction fails and is 
invalidated, making all previous and all subsequent statements fail 
until you call rollback (you cannot call commit on a failed 
transaction).

For bioperl-db and the granularity used by load_seqdatabase.pl, as a 
simple example this means on Postgres that if insertion of a dbxref 
fails, at that point the entire transaction is aborted, i.e., the 
previously inserted bioentry with sequence, features, comments, etc all 
go away. In practice this doesn't happen with bioperl-db because 
dbxrefs are cached and looked up first; however what does occur is the 
multiple associations of the same bioentry to the same dbxref, to give 
an example, which is prohibited by a unique key constraint. If this 
happens, the respective sequence entry is lost.

Here's the possible solutions.

1) Turn off transactions for PostgreSQL, i.e., run in auto-commit mode. 
Given the fact that Pg is a natively transactional database I find this 
option possible but sad. In addition, there would have to be code that 
specifically for PostgreSQL deletes the sequence entry if there was a 
failure during a particular sequence entry. (Otherwise rolling back the 
transaction takes care of cleaning up possibly incomplete rows.) On the 
plus side, this is probably the simplest one to implement.

2) Look up every record before insertion. On the plus side of things, 
this would maintain transactions. On the downside, entities with a 
finite number of records are already cached and looked up before insert 
(examples being dbxref, reference, ontology_term). Those that are not 
looked up are potentially infinite in number, meaning that 95% of the 
time the record to be inserted will not already exist. A prior lookup 
will be a waste of time in 95% of cases. I.e., this option will slow 
down performance.

3) Separate the look-up into PL/PgSQL code in the database. Instead of 
issuing a direct INSERT you call a stored procedure that looks up the 
entry and inserts it if not yet present. The advantage of this option 
is that it keeps the bioperl-db layout largely unaffected and hence 
treats all RDBMSs relatively equal (i.e., cares least about RDBMS 
idiosyncrasies). The downside is that this means that the Pg version of 
Biosql can't be fully auto-generated anymore from the MySQL version (I 
don't want to auto-generate the PL/PgSQL procedures from a MySQL schema 
definition). Also, people say PL/PgSQL is not the fastest thing out 
there.

Let me know your thoughts and votes. There may easily be more options, 
feel free to share.

	-hilmar
-- 
-------------------------------------------------------------
Hilmar Lapp                            email: lapp at gnf.org
GNF, San Diego, Ca. 92121              phone: +1-858-812-1757
-------------------------------------------------------------



More information about the Bioperl-l mailing list