Anonymous avatar Anonymous committed 5387283

reorganize

Comments (0)

Files changed (9)

Empty file added.

+import settings
+from django.core.management import setup_environ
+setup_environ(settings)
+
+import types
+
+from django.core.management.commands.syncdb import *
+from altersql import sql_create_model__custom
+from acid.utils import exc_str
+
+class Command(NoArgsCommand):
+    option_list = NoArgsCommand.option_list + (
+        make_option('--noinput', action='store_false', dest='interactive', default=True,
+            help='Tells Django to NOT prompt the user for input of any kind.'),
+        make_option('--database', action='store', dest='database',
+            default=DEFAULT_DB_ALIAS, help='Nominates a database to synchronize. '
+                'Defaults to the "default" database.'),
+        make_option('--app', action='store', dest='application',
+            default=None, help='Select app if need'),
+        make_option('--showsql', action='store_true', dest='showsql',
+            default=False, help='Show sql queries'),
+    )
+    help = "Create the database tables for all apps in INSTALLED_APPS whose tables haven't already been created."
+
+    def handle_noargs(self, **options):
+
+        verbosity = int(options.get('verbosity', 1))
+        interactive = options.get('interactive')
+        show_traceback = options.get('traceback', False)
+        application = options.get('application', None)
+        showsql = options.get('showsql', False)
+
+        # Stealth option -- 'load_initial_data' is used by the testing setup
+        # process to disable initial fixture loading.
+        load_initial_data = options.get('load_initial_data', True)
+
+        self.style = no_style()
+
+        # Import the 'management' module within each installed app, to register
+        # dispatcher events.
+        for app_name in settings.INSTALLED_APPS:
+            try:
+                import_module('.management', app_name)
+            except ImportError, exc:
+                # This is slightly hackish. We want to ignore ImportErrors
+                # if the "management" module itself is missing -- but we don't
+                # want to ignore the exception if the management module exists
+                # but raises an ImportError for some reason. The only way we
+                # can do this is to check the text of the exception. Note that
+                # we're a bit broad in how we check the text, because different
+                # Python implementations may not use the same text.
+                # CPython uses the text "No module named management"
+                # PyPy uses "No module named myproject.myapp.management"
+                msg = exc.args[0]
+                if not msg.startswith('No module named') or 'management' not in msg:
+                    raise
+
+        db = options.get('database', DEFAULT_DB_ALIAS)
+        connection = connections[db]
+        cursor = connection.cursor()
+
+        # Get a list of already installed *models* so that references work right.
+        tables = connection.introspection.table_names()
+        seen_models = connection.introspection.installed_models(tables)
+        created_models = set()
+        pending_references = {}
+
+        # Build the manifest of apps and models that are to be synchronized
+        all_models = [
+            (app.__name__.split('.')[-2],
+                [m for m in models.get_models(app, include_auto_created=True)
+                if router.allow_syncdb(db, m)])
+            for app in models.get_apps()
+        ]
+        all_models = [
+            (app, mods)
+            for app, mods in all_models if application == None or app == application
+        ]         
+        def model_installed(model):
+            opts = model._meta
+            converter = connection.introspection.table_name_converter
+            return not ((converter(opts.db_table) in tables) or
+                (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables))
+
+        manifest = SortedDict(
+            (app_name, filter(model_installed, model_list))
+            for app_name, model_list in all_models
+        )
+
+        # Create the tables for each model
+        if verbosity >= 1:
+            if application:
+                print 'Selected app: %s' % application
+#                print 'apps: ', models.get_apps()
+            print "Creating tables ..."
+        for app_name, model_list in manifest.items():
+            for model in model_list:
+                # Create the model's database table, if it doesn't already exist.
+                if verbosity >= 3:
+                    print "Processing %s.%s model" % (app_name, model._meta.object_name)
+                sql, references = connection.creation.sql_create_model(model, self.style, seen_models)
+                seen_models.add(model)
+                created_models.add(model)
+                for refto, refs in references.items():
+                    pending_references.setdefault(refto, []).extend(refs)
+                    if refto in seen_models:
+                        sql.extend(connection.creation.sql_for_pending_references(refto, self.style, pending_references))
+                sql.extend(connection.creation.sql_for_pending_references(model, self.style, pending_references))
+                if verbosity >= 1 and sql:
+                    print "Creating table %s" % model._meta.db_table
+                for statement in sql:
+                    cursor.execute(statement)
+                tables.append(connection.introspection.table_name_converter(model._meta.db_table))
+
+
+        transaction.commit_unless_managed(using=db)
+
+        # 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, db)
+
+        # The connection may have been closed by a syncdb handler.
+        cursor = connection.cursor()
+
+        # Install custom SQL for the app (but only if this
+        # is a model we've just created)
+        if verbosity >= 1:
+            print "Installing custom SQL ..."
+            
+#        from django.core.management.color import no_style
+        
+#        cstyle = no_style()
+
+        connection.creation.sql_create_model__old = connection.creation.sql_create_model
+        connection.creation.sql_create_model = types.MethodType(sql_create_model__custom, connection.creation)
+            
+#        import MyS
+
+
+            
+        for app_name, model_list in all_models:
+            for model in model_list:
+                print 'Altering %s ...' % model._meta.object_name
+                alter_sql, refs = connection.creation.sql_create_model(model, self.style)
+                for sql in alter_sql:
+                    try:
+                        if showsql:
+                            print '>>>', sql , '<<<'
+                        cursor.execute(sql)
+                    except Exception, e:
+                        sys.stderr.write("Failed to install custom SQL for %s.%s model: %s\n" % \
+                                            (app_name, model._meta.object_name, e))
+                        if show_traceback:
+                            import traceback
+                            traceback.print_exc()
+                        transaction.rollback_unless_managed(using=db)
+                    else:
+                        transaction.commit_unless_managed(using=db)
+#                    except:
+#                        e = exc_str()
+#                        if not 'already exists' in e and not 'Warning' in e:
+#                            print app_name, model._meta.object_name, e
+            
+        for app_name, model_list in manifest.items():
+            for model in model_list:
+                if model in created_models:
+                    custom_sql = custom_sql_for_model(model, self.style, connection)
+                    if custom_sql:
+                        if verbosity >= 2:
+                            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\n" % \
+                                                (app_name, model._meta.object_name, e))
+                            if show_traceback:
+                                import traceback
+                                traceback.print_exc()
+                            transaction.rollback_unless_managed(using=db)
+                        else:
+                            transaction.commit_unless_managed(using=db)
+                    else:
+                        if verbosity >= 3:
+                            print "No custom SQL for %s.%s model" % (app_name, model._meta.object_name)
+
+        if verbosity >= 1:
+            print "Installing indexes ..."
+        # Install SQL indicies for all newly created models
+        for app_name, model_list in all_models:
+            for model in model_list:
+#                if model in created_models:
+                index_sql = connection.creation.sql_indexes_for_model(model, self.style)
+                if index_sql:
+                    if verbosity >= 2:
+                        print "Installing index for %s.%s model" % (app_name, model._meta.object_name)
+                    for sql in index_sql:
+                        try:
+                            cursor.execute(sql)
+                        except Exception, e:
+                            sys.stderr.write("Failed to install index for %s.%s model: %s\n" % \
+                                                (app_name, model._meta.object_name, e))
+                            transaction.rollback_unless_managed(using=db)
+                        else:
+                            transaction.commit_unless_managed(using=db)
+
+        # Load initial_data fixtures (unless that has been disabled)
+        if load_initial_data:
+            from django.core.management import call_command
+            call_command('loaddata', 'initial_data', verbosity=verbosity, database=db)
+
+#import sys
+#sys.modules["django.core.management.commands.syncdb"] = sys.modules["django_snippets.alterdb"]

alterdb__creation.py

+import settings
+from django.core.management import setup_environ
+setup_environ(settings)
+
+from django.db.backends.creation import *
+
+BaseDatabaseCreationOld = BaseDatabaseCreation
+
+class BaseDatabaseCreation(object):
+    data_types = {}
+
+    def __init__(self, connection):
+        print '>>>>BaseDatabaseCreation'
+        self.connection = connection
+
+import sys
+sys.modules["django.db.backends.creation"] = sys.modules["django_snippets.alterdb__creation"]
+import settings
+from django.core.management import setup_environ
+setup_environ(settings)
+
+from django.core.management.sql import *
+
+import sys
+sys.modules["django.core.management.sql"] = sys.modules["django_snippets.altersql"]
+
+
+#import os
+#import re
+#
+#from django.conf import settings
+#from django.core.management.base import CommandError
+#from django.db import models
+#from django.db.models import get_models
+
+def sql_indexes(app, style, connection):
+    "Returns a list of the CREATE INDEX SQL statements for all models in the given app."
+    output = []
+
+#    connection.creation.sql_indexes_for_model__old = connection.creation.sql_indexes_for_model
+#    connection.creation.sql_indexes_for_model = types.MethodType(sql_indexes_for_model__custom, connection.creation)
+    
+    for model in models.get_models(app):
+        output.extend(connection.creation.sql_indexes_for_model(model, style))
+    return output
+
+
+
+def sql_all(app, style, connection):
+    "Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
+    print '--- custom sql_all ---'
+    return sql_create(app, style, connection) + sql_custom(app, style, connection) + sql_indexes(app, style, connection)
+
+def safe_add_column(qn, table, column, type):
+#    s = """
+#        
+#DELIMITER $$
+#
+#DROP PROCEDURE IF EXISTS upgrade_database_1_0_to_2_0 $$
+#CREATE PROCEDURE upgrade_database_1_0_to_2_0()
+#BEGIN
+#
+#    IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
+#            AND COLUMN_NAME='%s' AND TABLE_NAME='%s') ) THEN
+#        ALTER TABLE %s ADD %s %s;
+#    END IF;
+#
+#END $$
+#
+#CALL upgrade_database_1_0_to_2_0() $$
+#
+#DELIMITER ;
+#        """ % (column, table, qn(table), qn(column), type)
+##    return s.strip().split('\n') 
+#    return s 
+
+#    s = [
+#        
+#        
+#        "DROP PROCEDURE IF EXISTS upgrade_database_1_0_to_2_0;",
+##        """DELIMITER $$""",
+#        """
+#        CREATE PROCEDURE upgrade_database_1_0_to_2_0()
+#        BEGIN
+#        
+#            IF NOT EXISTS( (SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()
+#                    AND COLUMN_NAME='%s' AND TABLE_NAME='%s') ) THEN
+#                ALTER TABLE %s ADD %s %s;
+#            END IF;
+#        
+#        END;""" % (column, table, qn(table), qn(column), type),
+##        """DELIMITER ;""", 
+#    
+#        "CALL upgrade_database_1_0_to_2_0();",
+#        
+#    ]
+#        
+    
+    type_mod = type.replace('UNIQUE', '').replace('PRIMARY KEY', '')
+    type_mod.replace
+   
+    s = [
+        """ALTER TABLE %s ADD COLUMN %s %s;""" % (qn(table), qn(column), type),        
+        """ALTER TABLE %s MODIFY COLUMN %s %s;""" % (qn(table), qn(column), type_mod),        
+#        """ALTER TABLE %s CHANGE COLUMN %s %s %s;""" % tuple([qn(table)] + [qn(column)]*2 + [type]),         
+    ]    
+    
+    return s 
+#    return ['\n'.join(s)] 
+
+
+def sql_create_model__custom(self, model, style, known_models=set()):
+    """
+    Returns the SQL required to create a single model, as a tuple of:
+        (list_of_sql, pending_references_dict)
+    """
+    
+#    print 'sql_create_model__custom'
+    
+    opts = model._meta
+    if not opts.managed or opts.proxy:
+        return [], {}
+    final_output = []
+    table_output = []
+    table_output_dict = {}
+    pending_references = {}
+    qn = self.connection.ops.quote_name
+    for f in opts.local_fields:
+        col_type = f.db_type(connection=self.connection)
+        tablespace = f.db_tablespace or opts.db_tablespace
+        if col_type is None:
+            # Skip ManyToManyFields, because they're not represented as
+            # database columns in this table.
+            continue
+        # Make the definition (e.g. 'foo VARCHAR(30)') for this field.
+        field_output = [style.SQL_FIELD(qn(f.column)),
+            style.SQL_COLTYPE(col_type)]
+        if not f.null:
+            field_output.append(style.SQL_KEYWORD('NOT NULL'))
+        if f.primary_key:
+            field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
+        elif f.unique:
+            field_output.append(style.SQL_KEYWORD('UNIQUE'))
+        if tablespace and f.unique:
+            # We must specify the index tablespace inline, because we
+            # won't be generating a CREATE INDEX statement for this field.
+            field_output.append(self.connection.ops.tablespace_sql(tablespace, inline=True))
+        if f.rel:
+            ref_output, pending = self.sql_for_inline_foreign_key_references(f, known_models, style)
+            if pending:
+                pr = pending_references.setdefault(f.rel.to, []).append((model, f))
+            else:
+                field_output.extend(ref_output)
+        table_output_dict[f.column] = field_output[1:]
+        table_output.append(' '.join(field_output))
+    for field_constraints in opts.unique_together:
+        table_output.append(style.SQL_KEYWORD('UNIQUE') + ' (%s)' % \
+            ", ".join([style.SQL_FIELD(qn(opts.get_field(f).column)) for f in field_constraints]))
+
+    full_statement = [style.SQL_KEYWORD('CREATE TABLE IF NOT EXISTS') + ' ' + style.SQL_TABLE(qn(opts.db_table)) + ' (']
+#    print 'table_output', '\n'.join(table_output)
+    for i, line in enumerate(table_output): # Combine and add commas.
+        full_statement.append('    %s%s' % (line, i < len(table_output)-1 and ',' or ''))
+    full_statement.append(')')
+    if opts.db_tablespace:
+        full_statement.append(self.connection.ops.tablespace_sql(opts.db_tablespace))
+    full_statement.append(';')
+    final_output.append('\n'.join(full_statement))
+
+    if opts.has_auto_field:
+        # Add any extra SQL needed to support auto-incrementing primary keys.
+        auto_column = opts.auto_field.db_column or opts.auto_field.name
+        autoinc_sql = self.connection.ops.autoinc_sql(opts.db_table, auto_column)
+        if autoinc_sql:
+            for stmt in autoinc_sql:
+                final_output.append(stmt)
+    
+#    print 'table_output_dict', table_output_dict
+    for col, out in table_output_dict.items():        
+        s = safe_add_column(qn, opts.db_table, col, ' '.join(out))
+#        print s
+#        final_output.append(s)
+#        final_output.append('\n'.join(s))
+        final_output.extend(s)
+
+    return final_output, pending_references
+
+import types
+
+def sql_create(app, style, connection):
+    "Returns a list of the CREATE TABLE SQL statements for the given app."
+
+    print '--- custom sql_create ---'
+
+    if connection.settings_dict['ENGINE'] == 'django.db.backends.dummy':
+        # This must be the "dummy" database backend, which means the user
+        # hasn't set ENGINE for the databse.
+        raise CommandError("Django doesn't know which syntax to use for your SQL statements,\n" +
+            "because you haven't specified the ENGINE setting for the database.\n" +
+            "Edit your settings file and change DATBASES['default']['ENGINE'] to something like\n" +
+            "'django.db.backends.postgresql' or 'django.db.backends.mysql'.")
+
+    # Get installed models, so we generate REFERENCES right.
+    # We trim models from the current app so that the sqlreset command does not
+    # generate invalid SQL (leaving models out of known_models is harmless, so
+    # we can be conservative).
+    app_models = models.get_models(app, include_auto_created=True)
+    final_output = []
+    tables = connection.introspection.table_names()
+    known_models = set([model for model in connection.introspection.installed_models(tables) if model not in app_models])
+    pending_references = {}
+
+    connection.creation.sql_create_model__old = connection.creation.sql_create_model
+    connection.creation.sql_create_model = types.MethodType(sql_create_model__custom, connection.creation)
+
+#    for model in app_models[0:1]:   
+    for model in app_models:   
+        output, references = connection.creation.sql_create_model(model, style, known_models)
+#        print '\n'.join(output)
+        final_output.extend(output)
+        for refto, refs in references.items():
+            pending_references.setdefault(refto, []).extend(refs)
+            if refto in known_models:
+                final_output.extend(connection.creation.sql_for_pending_references(refto, style, pending_references))
+        final_output.extend(connection.creation.sql_for_pending_references(model, style, pending_references))
+        # Keep track of the fact that we've created the table for this model.
+        known_models.add(model)
+
+    # Handle references to tables that are from other apps
+    # but don't exist physically.
+    not_installed_models = set(pending_references.keys())
+    if not_installed_models:
+        alter_sql = []
+        for model in not_installed_models:
+            alter_sql.extend(['-- ' + sql for sql in
+                connection.creation.sql_for_pending_references(model, style, pending_references)])
+        if alter_sql:
+            final_output.append('-- The following references should be added but depend on non-existent tables:')
+            final_output.extend(alter_sql)
+
+    return final_output
+
+def sql_custom(app, style, connection):
+    "Returns a list of the custom table modifying SQL statements for the given app."
+    output = []
+
+    app_models = get_models(app)
+    app_dir = os.path.normpath(os.path.join(os.path.dirname(app.__file__), 'sql'))
+
+    for model in app_models:
+        out = custom_sql_for_model(model, style, connection)
+#        print out
+        output.extend(out)
+
+    return output
+#
+#def sql_indexes(app, style, connection):
+#    "Returns a list of the CREATE INDEX SQL statements for all models in the given app."
+#    output = []
+#    for model in models.get_models(app):
+#        output.extend(connection.creation.sql_indexes_for_model(model, style))
+#    return output
+#
+#def sql_all(app, style, connection):
+#    "Returns a list of CREATE TABLE SQL, initial-data inserts, and CREATE INDEX SQL for the given module."
+#    return sql_create(app, style, connection) + sql_custom(app, style, connection) + sql_indexes(app, style, connection)
+#
+
+def custom_sql_for_model(model, style, connection):
+#    print '--- custom custom_sql_for_model ---'
+    opts = model._meta
+    app_dir = os.path.normpath(os.path.join(os.path.dirname(models.get_app(model._meta.app_label).__file__), 'sql'))
+    output = []
+
+    # Post-creation SQL should come before any initial SQL data is loaded.
+    # However, this should not be done for models that are unmanaged or
+    # for fields that are part of a parent model (via model inheritance).
+    if opts.managed:
+        post_sql_fields = [f for f in opts.local_fields if hasattr(f, 'post_create_sql')]
+        for f in post_sql_fields:
+            output.extend(f.post_create_sql(style, model._meta.db_table))
+
+    # Some backends can't execute more than one SQL statement at a time,
+    # so split into separate statements.
+    statements = re.compile(r";[ \t]*$", re.M)
+
+    # Find custom SQL, if it's available.
+    backend_name = connection.settings_dict['ENGINE'].split('.')[-1]
+    sql_files = [os.path.join(app_dir, "%s.%s.sql" % (opts.object_name.lower(), backend_name)),
+                 os.path.join(app_dir, "%s.sql" % opts.object_name.lower())]
+    for sql_file in sql_files:
+        if os.path.exists(sql_file):
+            fp = open(sql_file, 'U')
+            for statement in statements.split(fp.read().decode(settings.FILE_CHARSET)):
+                # Remove any comments from the file
+                statement = re.sub(ur"--.*([\n\Z]|$)", "", statement)
+                if statement.strip():
+                    output.append(statement + u";")
+            fp.close()
+
+    return output
+#
+#
+#def emit_post_sync_signal(created_models, verbosity, interactive, db):
+#    # Emit the post_sync signal for every application.
+#    for app in models.get_apps():
+#        app_name = app.__name__.split('.')[-2]
+#        if verbosity >= 2:
+#            print "Running post-sync handlers for application", app_name
+#        models.signals.post_syncdb.send(sender=app, app=app,
+#            created_models=created_models, verbosity=verbosity,
+#            interactive=interactive, db=db)
+
+custom_sql_for_model_old = custom_sql_for_model
+def custom_sql_for_model(model, style, connection):
+#    print 'custom_sql_for_model'
+    return []
+
+
+from django.core.management.commands.sqlall import *
+
+import sys
+if 'altersql' in sys.argv:
+    idx = sys.argv.index('altersql')
+    sys.argv.remove('altersql')
+    sys.argv.insert(idx, 'sqlall')
+    
+    sys.argv
+    print 'set custom sql'
+    import django_snippets.altersql
+
+if 'alterdb' in sys.argv:
+    idx = sys.argv.index('alterdb')
+    sys.argv.remove('alterdb')
+    sys.argv.insert(idx, 'syncdb')
+    
+    sys.argv
+#    print '>>>> set custom syncdb'
+#    import django_snippets.alterdb__creation
+    print '>>>> set custom sql'
+    import django_snippets.altersql
+    import django_snippets.alterdb

Empty file added.

Add a comment to this file

management/commands/__init__.py

Empty file added.

management/commands/alterdb.py

+from ...alterdb import *

management/commands/altersql.py

+from ...altersql import *
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.