Added a custom Django backend that's Postgres-schema aware.
authorgfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Sun, 7 Feb 2010 22:46:16 +0000 (22:46 +0000)
committergfawcett <gfawcett@6d9bc8c9-1ec2-4278-b937-99fde70a366f>
Sun, 7 Feb 2010 22:46:16 +0000 (22:46 +0000)
commit34a5d65ec1113239adffb11d352c9f9e6bded24b
tree98638f53cf891d4b8892c6fde871f11cd700fe56
parentfb3ff97770ab30b3cd6babe33c691438b2fc1e30
Added a custom Django backend that's Postgres-schema aware.

I've written a Django 'backend' for Postgres that can both:

* allow a Django model to be designed, whose tables exist in multiple
  schemas; and

* inspect an existing Postgres database with multiple schemas, and
  generate a decent Django model from it.

The backend is in 'evergreen/backends', and there is a supporting
Django 'management command' in 'evergreen/management'. The management
command is only needed if you want to inspect a database and generate
a Django model.

You can use the backend without the inpsector; but the inspector
depends upon the backend.

---------------
The Backend
---------------

The backend is an extension of the Postgres 'psycopg2' backend. You
must have psycopg2 installed if you want to use this backend.

To activate the backend, change your settings.py, and change
DATABASE_ENGINE to:

DATABASE_ENGINE = 'conifer.evergreen.backends.postgresql_with_schemas'

In your Django models file, you can specify the schema for each
model's table like this:

  class OrgUnit(models.Model):
      class Meta:
          db_table = u'actor.ou'

      id = models.IntegerField(primary_key=True)
      ...

If you're trying to remain backend-agnostic, and allow your model to
work with RDBMS backends other than Postgres, then you can do
something like this:

  POSTGRES_SCHEMAS = True  # set to false if not using postgres...

  class OrgUnit(models.Model):
      class Meta:
          db_table = u'actor.ou' if POSTGRES_SCHEMAS else u'actor_ou'

      id = models.IntegerField(primary_key=True)
      ...

So, if you ask to use Postgres schemas, you'll get a 'dot' in the
table name, otherwise you won't. Note that you could dynamically set
POSTGRES_SCHEMAS based on the value of DATABASE_ENGINE in settings.py.

---------------
The Inpsector
---------------

The inspector is the bit that can generate a Django model from an
existing database. Django comes with a builtin inspector: a management
command called 'inspectdb'. Unfortunately, 'inspectdb' is not
schema-aware, so I've added a custom management command called
'inspectdb_evergreen'. (That's a misnomer, it's not particularly
evergreen specific.)

To use the schema-aware inspector, you must do the following:

* Edit your settings.py to point to your database:

  DATABASE_NAME   = 'mydatabase'
  DATABASE_HOST   = 'dbserver'

* Specify the new custom backend:

  DATABASE_ENGINE = 'conifer.evergreen.backends.postgresql_with_schemas'

* Specify which schemas you want to inspect. If you want to inspect
  the 'public' schema, you must add it explicitly. There is no default:
  you must be explicit.

  DATABASE_PG_SCHEMAS = ['actor','asset','config','permission','reserves']

* Finally, add 'evergreen' to the installed apps, so that the custom
  management command will be available.

  INSTALLED_APPS = (
      'eg_schema_experiment.evergreen',
      'django.contrib.auth',
      ...)

* Save your settings.py changes, and at the command line, change to
the project directory (where settings.py is located) and run:

  ./manage.py inspectdb_evergreen

This will dump a sample model to standard output. Most likely you want
to first create a directory for your application, and then dump this
model into that directory, e.g:

  ./manage.py startapp myapp
  ./manage inspectdb_evergreen > myapp/models.py

And then add your new app to the installed apps:

  INSTALLED_APPS = (
      'conifer.evergreen',
      'django.contrib.auth',
      ...,
      'conifer.myapp')

...and you're ready to start writing your Django application.

Note that the model generated by 'inspectdb_evergreen' uses the
'POSTGRES_SCHEMAS' technique described above to keep the model
database-agnostic: that is, it's possible to configure the model to
work with databases that do not use schemas, such as MySQL or SQLite.

git-svn-id: svn://svn.open-ils.org/ILS-Contrib/servres/branches/eg-schema-experiment@768 6d9bc8c9-1ec2-4278-b937-99fde70a366f
15 files changed:
.gitignore
conifer/evergreen/__init__.py [new file with mode: 0644]
conifer/evergreen/backends/__init__.py [new file with mode: 0644]
conifer/evergreen/backends/postgresql_with_schemas/__init__.py [new file with mode: 0755]
conifer/evergreen/backends/postgresql_with_schemas/base.py [new file with mode: 0755]
conifer/evergreen/backends/postgresql_with_schemas/introspection.py [new file with mode: 0755]
conifer/evergreen/backends/postgresql_with_schemas/operations.py [new file with mode: 0644]
conifer/evergreen/management/__init__.py [new file with mode: 0644]
conifer/evergreen/management/commands/__init__.py [new file with mode: 0644]
conifer/evergreen/management/commands/inspectdb_evergreen.py [new file with mode: 0644]
conifer/robin/__init__.py [new file with mode: 0755]
conifer/robin/models.py [new file with mode: 0755]
conifer/robin/tests.py [new file with mode: 0755]
conifer/robin/views.py [new file with mode: 0755]
conifer/settings.py