Django

Code

Changeset 5789

Show
Ignore:
Timestamp:
08/03/07 11:48:51 (1 year ago)
Author:
danderson
Message:

schema-evolution:
moved most of the sql_evolve code into its own module

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/schema-evolution/django/core/management.py

    r5788 r5789  
    482482            ) 
    483483    return output 
    484  
     484     
    485485def get_sql_evolution(app): 
    486486    "Returns SQL to update an existing schema to match the existing models." 
     487    import schema_evolution 
    487488    from django.db import get_creation_module, models, backend, get_introspection_module, connection 
    488489    data_types = get_creation_module().DATA_TYPES 
     
    533534    for klass in app_models: 
    534535         
    535         output, new_table_name = get_sql_evolution_check_for_changed_model_name(klass) 
     536        output, new_table_name = schema_evolution.get_sql_evolution_check_for_changed_model_name(klass) 
    536537        final_output.extend(output) 
    537538         
    538         output = get_sql_evolution_check_for_changed_field_flags(klass, new_table_name) 
     539        output = schema_evolution.get_sql_evolution_check_for_changed_field_flags(klass, new_table_name) 
    539540        final_output.extend(output) 
    540541     
    541         output = get_sql_evolution_check_for_changed_field_name(klass, new_table_name) 
     542        output = schema_evolution.get_sql_evolution_check_for_changed_field_name(klass, new_table_name) 
    542543        final_output.extend(output) 
    543544         
    544         output = get_sql_evolution_check_for_new_fields(klass, new_table_name) 
     545        output = schema_evolution.get_sql_evolution_check_for_new_fields(klass, new_table_name) 
    545546        final_output.extend(output) 
    546547         
    547         output = get_sql_evolution_check_for_dead_fields(klass, new_table_name) 
     548        output = schema_evolution.get_sql_evolution_check_for_dead_fields(klass, new_table_name) 
    548549        final_output.extend(output) 
    549550         
    550551    return final_output 
     552     
    551553get_sql_evolution.help_doc = "Returns SQL to update an existing schema to match the existing models." 
    552554get_sql_evolution.args = APP_ARGS 
    553  
    554 def get_sql_evolution_check_for_new_fields(klass, new_table_name): 
    555     "checks for model fields that are not in the existing data structure" 
    556     from django.db import backend, get_creation_module, models, get_introspection_module, connection 
    557     data_types = get_creation_module().DATA_TYPES 
    558     cursor = connection.cursor() 
    559     introspection = get_introspection_module() 
    560     opts = klass._meta 
    561     output = [] 
    562     db_table = klass._meta.db_table 
    563     if new_table_name:  
    564         db_table = new_table_name 
    565     for f in opts.fields: 
    566         existing_fields = introspection.get_columns(cursor,db_table) 
    567         if f.column not in existing_fields and (not f.aka or f.aka not in existing_fields and len(set(f.aka) & set(existing_fields))==0): 
    568             rel_field = f 
    569             data_type = f.get_internal_type() 
    570             col_type = data_types[data_type] 
    571             if col_type is not None: 
    572                 output.extend( backend.get_add_column_sql( db_table, f.column, style.SQL_COLTYPE(col_type % rel_field.__dict__), f.null, f.unique, f.primary_key ) ) 
    573     return output 
    574  
    575 def get_sql_evolution_check_for_changed_model_name(klass): 
    576     from django.db import backend, get_creation_module, models, get_introspection_module, connection 
    577     cursor = connection.cursor() 
    578     introspection = get_introspection_module() 
    579     table_list = introspection.get_table_list(cursor) 
    580     if klass._meta.db_table in table_list: 
    581         return [], None 
    582     if klass._meta.aka in table_list: 
    583         return backend.get_change_table_name_sql( klass._meta.db_table, klass._meta.aka), klass._meta.aka 
    584     elif len(set(klass._meta.aka) & set(table_list))==1: 
    585         return backend.get_change_table_name_sql( klass._meta.db_table, klass._meta.aka[0]), klass._meta.aka[0] 
    586     else: 
    587         return [], None 
    588      
    589 def get_sql_evolution_check_for_changed_field_name(klass, new_table_name): 
    590     from django.db import backend, get_creation_module, models, get_introspection_module, connection 
    591     data_types = get_creation_module().DATA_TYPES 
    592     cursor = connection.cursor() 
    593     introspection = get_introspection_module() 
    594     opts = klass._meta 
    595     output = [] 
    596     db_table = klass._meta.db_table 
    597     if new_table_name:  
    598         db_table = new_table_name 
    599     for f in opts.fields: 
    600         existing_fields = introspection.get_columns(cursor,db_table) 
    601         if f.column not in existing_fields and f.aka and (f.aka in existing_fields or len(set(f.aka) & set(existing_fields)))==1: 
    602             old_col = None 
    603             if isinstance( f.aka, str ): 
    604                 old_col = f.aka 
    605             else: 
    606                 old_col = f.aka[0] 
    607             rel_field = f 
    608             data_type = f.get_internal_type() 
    609             col_type = data_types[data_type] 
    610             if col_type is not None: 
    611                 col_def = style.SQL_COLTYPE(col_type % rel_field.__dict__) +' '+ style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')) 
    612                 if f.unique: 
    613                     col_def += style.SQL_KEYWORD(' UNIQUE') 
    614                 if f.primary_key: 
    615                     col_def += style.SQL_KEYWORD(' PRIMARY KEY') 
    616                 output.extend( backend.get_change_column_name_sql( klass._meta.db_table, introspection.get_indexes(cursor,db_table), old_col, f.column, col_def ) ) 
    617     return output 
    618      
    619 def get_sql_evolution_check_for_changed_field_flags(klass, new_table_name): 
    620     from django.db import backend, get_creation_module, models, get_introspection_module, connection 
    621     from django.db.models.fields import CharField, SlugField 
    622     from django.db.models.fields.related import RelatedField, ForeignKey 
    623     data_types = get_creation_module().DATA_TYPES 
    624     cursor = connection.cursor() 
    625     introspection = get_introspection_module() 
    626     opts = klass._meta 
    627     output = [] 
    628     db_table = klass._meta.db_table 
    629     if new_table_name:  
    630         db_table = new_table_name 
    631     for f in opts.fields: 
    632         existing_fields = introspection.get_columns(cursor,db_table) 
    633 #        print existing_fields 
    634         cf = None # current field, ie what it is before any renames 
    635         if f.column in existing_fields: 
    636             cf = f.column 
    637         elif f.aka in existing_fields: 
    638             cf = f.aka 
    639         elif f.aka and len(set(f.aka) & set(existing_fields))==1: 
    640             cf = f.aka[0] 
    641         else: 
    642             continue # no idea what column you're talking about - should be handled by get_sql_evolution_check_for_new_fields()) 
    643         data_type = f.get_internal_type() 
    644         if data_types.has_key(data_type): 
    645             column_flags = introspection.get_known_column_flags(cursor, db_table, cf) 
    646 #            print db_table, cf, column_flags 
    647             if column_flags['allow_null']!=f.null or \ 
    648                     ( not f.primary_key and isinstance(f, CharField) and column_flags['maxlength']!=str(f.maxlength) ) or \ 
    649                     ( not f.primary_key and isinstance(f, SlugField) and column_flags['maxlength']!=str(f.maxlength) ) or \ 
    650                     ( column_flags['unique']!=f.unique and ( settings.DATABASE_ENGINE!='postgresql' or not f.primary_key ) ) or \ 
    651                     column_flags['primary_key']!=f.primary_key: 
    652                     #column_flags['foreign_key']!=f.foreign_key: 
    653 #                print 'need to change' 
    654 #                print db_table, f.column, column_flags 
    655 #                print "column_flags['allow_null']!=f.null", column_flags['allow_null']!=f.null 
    656 #                print "not f.primary_key and isinstance(f, CharField) and column_flags['maxlength']!=str(f.maxlength)", not f.primary_key and isinstance(f, CharField) and column_flags['maxlength']!=str(f.maxlength) 
    657 #                print "not f.primary_key and isinstance(f, SlugField) and column_flags['maxlength']!=str(f.maxlength)", not f.primary_key and isinstance(f, SlugField) and column_flags['maxlength']!=str(f.maxlength) 
    658 #                print "column_flags['unique']!=f.unique", column_flags['unique']!=f.unique 
    659 #                print "column_flags['primary_key']!=f.primary_key", column_flags['primary_key']!=f.primary_key 
    660                 col_type = data_types[data_type] 
    661                 col_type_def = style.SQL_COLTYPE(col_type % f.__dict__) 
    662 #                col_def = style.SQL_COLTYPE(col_type % f.__dict__) +' '+ style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')) 
    663 #                if f.unique: 
    664 #                    col_def += ' '+ style.SQL_KEYWORD('UNIQUE') 
    665 #                if f.primary_key: 
    666 #                    col_def += ' '+ style.SQL_KEYWORD('PRIMARY KEY') 
    667                 output.extend( backend.get_change_column_def_sql( db_table, cf, col_type_def, f.null, f.unique, f.primary_key ) ) 
    668                     #print db_table, cf, f.maxlength, introspection.get_known_column_flags(cursor, db_table, cf) 
    669     return output 
    670  
    671 def get_sql_evolution_check_for_dead_fields(klass, new_table_name): 
    672     from django.db import backend, get_creation_module, models, get_introspection_module, connection 
    673     from django.db.models.fields import CharField, SlugField 
    674     from django.db.models.fields.related import RelatedField, ForeignKey 
    675     data_types = get_creation_module().DATA_TYPES 
    676     cursor = connection.cursor() 
    677     introspection = get_introspection_module() 
    678     opts = klass._meta 
    679     output = [] 
    680     db_table = klass._meta.db_table 
    681     if new_table_name:  
    682         db_table = new_table_name 
    683     suspect_fields = set(introspection.get_columns(cursor,db_table)) 
    684 #    print 'suspect_fields = ', suspect_fields 
    685     for f in opts.fields: 
    686 #        print 'f = ', f 
    687 #        print 'f.aka = ', f.aka 
    688         suspect_fields.discard(f.column) 
    689         suspect_fields.discard(f.aka) 
    690         if f.aka: suspect_fields.difference_update(f.aka) 
    691     if len(suspect_fields)>0: 
    692         output.append( '-- warning: the following may cause data loss' ) 
    693         for suspect_field in suspect_fields: 
    694             output.extend( backend.get_drop_column_sql( db_table, suspect_field ) ) 
    695         output.append( '-- end warning' ) 
    696     return output 
    697555 
    698556def get_sql_all(app):