Skip to content

Instantly share code, notes, and snippets.

@mmulich
Last active September 9, 2015 16:12
Show Gist options
  • Save mmulich/b204740439e684fbe982 to your computer and use it in GitHub Desktop.
Save mmulich/b204740439e684fbe982 to your computer and use it in GitHub Desktop.

What to do with triggers...

Our codebases use virtualenv installations, which helps to isolate the implemenation from external environmental factors.

Problems

  1. Installation of cnx-archive must happen globally and locally (virtualenv), which prone to errors due to two separate versions being installed. (This does not include the need/want to allow for multiple versions of the triggers to be installed on the same server.)
  2. Postgres and cnx-archive must be installed on the same server, which doesn't play nice with isolation of services (i.e. containers/jails).
  3. Installation of unused dependencies within the globally installed Python.

Solutions

Activate virtualenv when you connect to the DB

On each connection to the database we activate the virtualenv, which will make the packages within the virtualenv available for import.

A rough draft implementation of virtualenv activating within postgres has been mused at by reedstrm.

This approach has two major advantages to solve problems one and two.

  1. The installation happen once and only once, locally (within the virtualenv).
  2. More than one installation of the triggers can used (e.g. more than one virtualenv on the system, both of which contain cnx-archive).

However, this approach does not address problem two at all, because the Postgres instance would still need access to virtualenv (i.e. Postgres couldn't be run as an contained service).

On every connection to the database a virtualenv activation would be necessary. This means that each implementation (including psql) would need a custom connection sequence that included a call to activate virtualenv. In my (pumazi) opinion, this makes the solution fragile and prone to user error.

Separate the triggers into their on package

We split the triggers into their own package (e.g. cnx-archive-triggers). As part of initdb, we check that the version of the triggers package is correct (this is really only for developers). As part of application startup, we verify the version of the triggers package in use; and fail-to-start/warn when it's not correct.

This solves neither problem one or two, but does address problem three.

Separate the trigger logic into its own package

We inline (that is, put all the code within the sql function definition) as many of the triggers as possible and leave them within the cnx-archive codebase. This should allow for–or at least get close to allowing–one or more versions of the triggers to be installed on a server.

The logic that needs to be split into a separate global package will be the transforms code, currently found in cnxarchive.transforms. This package can eventually be eliminated since the contents of it are specific to legacy content.

This approach solves problems one and three, but does not address problem two, because the now globally installed trigger transform logic will require some external dependencies (e.g. lxml2 and xslt).

Don't import packages from the triggers

The implementation would would be to make all triggers stand-alone. Importing non standard library packages would be illegal by convention. This forces all the code to live within the trigger itself.

This approach solves problem one, two and three, because it does not require global installation.

Don't use triggers

Not feasible until legacy has been destroyed.

@karenc
Copy link

karenc commented Aug 31, 2015

I think separating the triggers into their own package and not importing archive code from triggers is probably the way to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment