Ticket #2229: m2m_syncdb.patch

File m2m_syncdb.patch, 5.3 KB (added by SmileyChris, 8 years ago)
  • django/core/management.py

     
    238238    return final_output
    239239
    240240def _get_many_to_many_sql_for_model(model):
    241     from django.db import backend, get_creation_module
    242241    from django.db.models import GenericRel
    243242
    244     data_types = get_creation_module().DATA_TYPES
    245 
    246243    opts = model._meta
    247244    final_output = []
    248245    for f in opts.many_to_many:
    249246        if not isinstance(f.rel, GenericRel):
    250             table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \
    251                 style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' (']
    252             table_output.append('    %s %s %s,' % \
    253                 (style.SQL_FIELD(backend.quote_name('id')),
    254                 style.SQL_COLTYPE(data_types['AutoField']),
    255                 style.SQL_KEYWORD('NOT NULL PRIMARY KEY')))
    256             table_output.append('    %s %s %s %s (%s)%s,' % \
    257                 (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
    258                 style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__),
    259                 style.SQL_KEYWORD('NOT NULL REFERENCES'),
    260                 style.SQL_TABLE(backend.quote_name(opts.db_table)),
    261                 style.SQL_FIELD(backend.quote_name(opts.pk.column)),
    262                 backend.get_deferrable_sql()))
    263             table_output.append('    %s %s %s %s (%s)%s,' % \
    264                 (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())),
    265                 style.SQL_COLTYPE(data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__),
    266                 style.SQL_KEYWORD('NOT NULL REFERENCES'),
    267                 style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)),
    268                 style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)),
    269                 backend.get_deferrable_sql()))
    270             table_output.append('    %s (%s, %s)' % \
    271                 (style.SQL_KEYWORD('UNIQUE'),
    272                 style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
    273                 style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name()))))
    274             table_output.append(');')
    275             final_output.append('\n'.join(table_output))
     247            final_output.append(_get_many_to_many_sql_for_field(f, opts))
    276248    return final_output
    277249
     250def _get_many_to_many_sql_for_field(f, opts):
     251    """
     252    Returns the SQL for creating a many-to-many table.
     253    Takes a many-to-many field and opts for the model it belongs to.
     254    """
     255    from django.db import backend, get_creation_module
     256    data_types = get_creation_module().DATA_TYPES
     257
     258    table_output = [style.SQL_KEYWORD('CREATE TABLE') + ' ' + \
     259        style.SQL_TABLE(backend.quote_name(f.m2m_db_table())) + ' (']
     260    table_output.append('    %s %s %s,' % \
     261        (style.SQL_FIELD(backend.quote_name('id')),
     262        style.SQL_COLTYPE(data_types['AutoField']),
     263        style.SQL_KEYWORD('NOT NULL PRIMARY KEY')))
     264    table_output.append('    %s %s %s %s (%s)%s,' % \
     265        (style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
     266        style.SQL_COLTYPE(data_types[get_rel_data_type(opts.pk)] % opts.pk.__dict__),
     267        style.SQL_KEYWORD('NOT NULL REFERENCES'),
     268        style.SQL_TABLE(backend.quote_name(opts.db_table)),
     269        style.SQL_FIELD(backend.quote_name(opts.pk.column)),
     270        backend.get_deferrable_sql()))
     271    table_output.append('    %s %s %s %s (%s)%s,' % \
     272        (style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name())),
     273        style.SQL_COLTYPE(data_types[get_rel_data_type(f.rel.to._meta.pk)] % f.rel.to._meta.pk.__dict__),
     274        style.SQL_KEYWORD('NOT NULL REFERENCES'),
     275        style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)),
     276        style.SQL_FIELD(backend.quote_name(f.rel.to._meta.pk.column)),
     277        backend.get_deferrable_sql()))
     278    table_output.append('    %s (%s, %s)' % \
     279        (style.SQL_KEYWORD('UNIQUE'),
     280        style.SQL_FIELD(backend.quote_name(f.m2m_column_name())),
     281        style.SQL_FIELD(backend.quote_name(f.m2m_reverse_name()))))
     282    table_output.append(');')
     283    return '\n'.join(table_output)
     284
    278285def get_sql_delete(app):
    279286    "Returns a list of the DROP TABLE SQL statements for the given app."
    280287    from django.db import backend, connection, models, get_introspection_module
     
    534541            table_list.append(model._meta.db_table)
    535542
    536543        for model in model_list:
    537             if model in created_models:
    538                 sql = _get_many_to_many_sql_for_model(model)
    539                 if sql:
    540                     if verbosity >= 2:
    541                         print "Creating many-to-many tables for %s.%s model" % (app_name, model._meta.object_name)
    542                     for statement in sql:
    543                         cursor.execute(statement)
     544            opts = model._meta
     545            for field in opts.many_to_many:
     546                if isinstance(field.rel, models.GenericRel) or field.m2m_db_table() in table_list:
     547                    continue
     548                sql = _get_many_to_many_sql_for_field(field, opts)
     549                if verbosity >= 2:
     550                    print "Creating many-to-many table %s for %s.%s model" % (field.m2m_db_table(), app_name, opts.object_name)
     551                cursor.execute(sql)
    544552
    545553        transaction.commit_unless_managed()
    546554
Back to Top