Skip to content

Commit

Permalink
corrected syncdb to run app management files prior to creating tables…
Browse files Browse the repository at this point in the history
…. Also added ability to fire signals on after-create.
  • Loading branch information
empty committed Jun 10, 2008
1 parent 345267f commit 3cc325f
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 5 deletions.
19 changes: 16 additions & 3 deletions django_sqlalchemy/management/commands/syncdb.py
@@ -1,5 +1,7 @@
from optparse import make_option
from django.conf import settings
from django.core.management.base import NoArgsCommand
from django_sqlalchemy.utils import CreationSniffer

class Command(NoArgsCommand):
option_list = NoArgsCommand.option_list + (
Expand All @@ -16,8 +18,19 @@ def handle_noargs(self, **options):
from django.core.management import call_command
from django.core.management.sql import emit_post_sync_signal

# TODO: create after_create listeners for all tables, capture
# who got created and then use that in a post sync signal
# Import the 'management' module within each installed app, to register
# dispatcher events.
for app_name in settings.INSTALLED_APPS:
try:
__import__(app_name + '.management', {}, {}, [''])
except ImportError, exc:
if not exc.args[0].startswith('No module named management'):
raise

# set up table listeners
sniffer = CreationSniffer()
for table in metadata.tables.values():
table.append_ddl_listener('after-create', sniffer)

metadata.create_all()
session.commit()
Expand All @@ -27,7 +40,7 @@ def handle_noargs(self, **options):

# Send the post_syncdb signal, so individual apps can do whatever they need
# to do at this point.
# emit_post_sync_signal(created_models, verbosity, interactive)
emit_post_sync_signal(sniffer.models, verbosity, interactive)

# load fixtures
call_command('loaddata', 'initial_data', verbosity=verbosity)
19 changes: 19 additions & 0 deletions django_sqlalchemy/management/sql.py
@@ -1,4 +1,5 @@
from django.db.models.loading import get_models
from django.core.management.sql import custom_sql_for_model
from sqlalchemy import create_engine
from django_sqlalchemy.backend import metadata, session

Expand All @@ -16,3 +17,21 @@ def _get_tables_for_app(app):
tables.append(model.__table__)
tables.extend([f.__table__ for f in model._meta.local_many_to_many])
return tables

def process_custom_sql(models, verbosity):
# TODO: complete this
# install custom sql for the specified models
for model in models:
custom_sql = custom_sql_for_model(model)
if custom_sql:
if verbosity >= 1:
print "Installing custom SQL for %s.%s model" % (app_name, model._meta.object_name)
try:
for sql in custom_sql:
cursor.execute(sql)
except Exception, e:
sys.stderr.write("Failed to install custom SQL for %s.%s model: %s" % \
(app_name, model._meta.object_name, e))
transaction.rollback_unless_managed()
else:
transaction.commit_unless_managed()
19 changes: 18 additions & 1 deletion django_sqlalchemy/utils.py
@@ -1,7 +1,20 @@
import types
from django.conf import settings
from django.core.management.sql import installed_models

__all__ = 'parse_db_uri', 'db_url', 'db_label', 'CreationSniffer'

class CreationSniffer(object):
def __init__(self):
self.tables = set()

def __call__(self, event, table, bind):
self.tables.add(table)

@property
def models(self):
return installed_models([table.name for table in self.tables])

__all__ = 'parse_db_uri', 'db_url', 'db_label'

def parse_db_uri():
"""
Expand All @@ -12,13 +25,15 @@ def parse_db_uri():
return (db_url, db_label)
db_url, db_label = parse_db_uri()


def unbound_method_to_callable(func_or_cls):
"""Adjust the incoming callable such that a 'self' argument is not required."""
if isinstance(func_or_cls, types.MethodType) and not func_or_cls.im_self:
return func_or_cls.im_func
else:
return func_or_cls


def MixIn(klass, mixin, include_private=True, ancestor=False):
if ancestor:
if mixin not in klass.__bases__:
Expand All @@ -40,9 +55,11 @@ def MixIn(klass, mixin, include_private=True, ancestor=False):
member = member.im_func
setattr(klass, name, member)


class MethodContainer(object):
pass


class ClassReplacer(object):
def __init__(self, klass, metaclass=None):
self.klass = klass
Expand Down
2 changes: 1 addition & 1 deletion tests/apps/settings.py
Expand Up @@ -12,7 +12,7 @@
'django_sqlalchemy',
# 'apps.blog',
'apps.events',
# 'django.contrib.auth',
'django.contrib.auth',
# 'apps.news',
# 'apps.norelations',
# 'apps.categories',
Expand Down

0 comments on commit 3cc325f

Please sign in to comment.