Skip to content

Commit

Permalink
Added a clear command so we can remove views before running a migration
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott Walton committed Jul 17, 2014
1 parent fad4b61 commit 94ed2f7
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 1 deletion.
28 changes: 28 additions & 0 deletions django_pgviews/management/commands/clear_pgviews.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from optparse import make_option
import logging

from django.core.management.base import NoArgsCommand
from django.db import models

from django_pgviews.view import clear_views


log = logging.getLogger('django_pgviews.sync_pgviews')


class Command(NoArgsCommand):
help = """Clear Postgres views. Use this before running a migration"""

def handle_noargs(self, **options):
"""
"""
for module in models.get_apps():
for status, view_cls, python_name in clear_views(module):
if status == 'DROPPED':
msg = 'dropped'
else:
msg = 'not dropped'
log.info("%(python_name)s (%(view_name)s): %(msg)s" % {
'python_name': python_name,
'view_name': view_cls._meta.db_table,
'msg': msg})
34 changes: 34 additions & 0 deletions django_pgviews/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,40 @@ def create_view(connection, view_name, view_query, update=True, force=False):
cursor_wrapper.close()


def clear_views(models_module):
"""Remove the database views for a given models_module."""
for name, view_cls in vars(models_module).iteritems():
if not (isinstance(view_cls, type) and
issubclass(view_cls, View) and
hasattr(view_cls, 'sql')):
continue

try:
cleared = clear_view(
connection, view_cls._meta.db_table)
except Exception, exc:
exc.view_cls = view_cls
exc.python_name = models_module.__name__ + '.' + name
raise
else:
yield cleared, view_cls, models_module.__name__ + '.' + name


def clear_view(connection, view_name):
"""
Remove a named view on connection.
"""
cursor_wrapper = connection.cursor()
cursor = cursor_wrapper.cursor
try:
cursor.execute('DROP VIEW IF EXISTS {0}'.format(view_name))

transaction.commit_unless_managed()
finally:
cursor_wrapper.close()
return u'DROPPED'.format(view=view_name)


class View(models.Model):

"""Helper for exposing Postgres views as Django models."""
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

setup(
name='django-pgviews',
version='0.0.2',
version='0.0.3',
description="Create and manage Postgres SQL Views in Django",
author='Scott Walton',
author_email='scott.walton@mypebble.co.uk',
Expand Down
9 changes: 9 additions & 0 deletions tests/test_project/test_project/viewtest/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ def test_views_have_been_created(self):
count, = cur.fetchone()
self.assertEqual(count, 3)

def test_clear_views(self):
call_command('clear_pgviews', *[], **{})
with closing(connection.cursor()) as cur:
cur.execute('''SELECT COUNT(*) FROM pg_views
WHERE viewname LIKE 'viewtest_%';''')

count, = cur.fetchone()
self.assertEqual(count, 0)

def test_wildcard_projection_gets_all_fields_from_projected_model(self):
foo_user = auth.models.User.objects.create(
username='foo', is_superuser=True)
Expand Down

0 comments on commit 94ed2f7

Please sign in to comment.