Ticket #2041: add_field_basics.diff

File add_field_basics.diff, 5.0 KB (added by ilias lazaridis <ilias@…>, 18 years ago)
  • P:/org/django/django/core/management.py

     
    128128get_sql_create.help_doc = "Prints the CREATE TABLE SQL statements for the given app name(s)."
    129129get_sql_create.args = APP_ARGS
    130130
     131#------------------------------------------------------------------------------
     132
     133def table_field_exists(klass, f):
     134    """
     135    Checks if a field is available within a table
     136   
     137    Limited implementation, verifies only field-name
     138
     139    Status: draft
     140    """   
     141    from django.db import backend, connection
     142
     143    cursor = connection.cursor()
     144    backend_column_name = f.column
     145
     146    cursor.execute('select * from %s where 1 = 0' % klass._meta.db_table )
     147   
     148    exist = False
     149    for col in cursor.description:
     150        if backend_column_name == col[0]:
     151            exist = True
     152            break
     153           
     154    return exist       
     155
     156#------------------------------------------------------------------------------
     157def _get_sql_table_evolve(klass):
     158    """
     159    Get the SQL required to evolve a single model.
     160
     161    Uses ALTER TABLE
     162   
     163    Status: draft, sqlite3 specific.
     164    """
     165    from django.db import backend
     166       
     167    final_output = []
     168    str = ''
     169    for f in klass._meta.fields:                   
     170        if not table_field_exists(klass, f):
     171            statement, ref = _get_sql_field_def(klass, f)
     172            field_def = ' '.join(statement)
     173                   
     174            full_statement = [style.SQL_KEYWORD('ALTER TABLE') + ' %s ADD COLUMN %s;' % \
     175                ( style.SQL_TABLE(backend.quote_name( klass._meta.db_table )), field_def) ]
     176            final_output.append('\n'.join(full_statement))
     177
     178    if final_output:
     179        full_statement = [style.SQL_KEYWORD('VACUUM') + ';']
     180        final_output.append('\n'.join(full_statement))         
     181                     
     182    return final_output
     183
     184#------------------------------------------------------------------------------
     185
     186def table_evolve(klass):
     187    """
     188    evolves the underlying table for a single model
     189   
     190    Status: draft
     191    """
     192    from django.db import backend, connection, transaction
     193
     194    print "Checking table  %s model" % klass.__name__
     195
     196    cursor = connection.cursor()
     197    statements = _get_sql_table_evolve(klass)
     198   
     199    if statements:
     200        print "Evolving table for Class %s" % klass.__name__
     201        for statement in statements:
     202            cursor.execute(statement)
     203
     204        transaction.commit_unless_managed()
     205       
     206#------------------------------------------------------------------------------
     207       
     208def _get_sql_field_def(klass, f, models_already_seen=set() ):
     209    """
     210    Get the SQL for a field definition
     211    """
     212   
     213    # copied from _get_sql_model_create
     214    # not neede lines are outcommented (will be removed after review)
     215
     216    from django.db import backend, get_creation_module, models
     217    data_types = get_creation_module().DATA_TYPES
     218
     219    #opts = klass._meta
     220    #final_output = []
     221    #table_output = []
     222    #pending_references = {}
     223
     224    if isinstance(f, models.ForeignKey):
     225        rel_field = f.rel.get_related_field()
     226        data_type = get_rel_data_type(rel_field)
     227    else:
     228        rel_field = f
     229        data_type = f.get_internal_type()
     230    col_type = data_types[data_type]
     231    if col_type is not None:
     232        # Make the definition (e.g. 'foo VARCHAR(30)') for this field.
     233        field_output = [style.SQL_FIELD(backend.quote_name(f.column)),
     234            style.SQL_COLTYPE(col_type % rel_field.__dict__)]
     235        field_output.append(style.SQL_KEYWORD('%sNULL' % (not f.null and 'NOT ' or '')))
     236        if f.unique:
     237            field_output.append(style.SQL_KEYWORD('UNIQUE'))
     238        if f.primary_key:
     239            field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
     240        if f.rel:
     241            if f.rel.to in models_already_seen:
     242                field_output.append(style.SQL_KEYWORD('REFERENCES') + ' ' + \
     243                    style.SQL_TABLE(backend.quote_name(f.rel.to._meta.db_table)) + ' (' + \
     244                    style.SQL_FIELD(backend.quote_name(f.rel.to._meta.get_field(f.rel.field_name).column)) + ')'
     245                )
     246            #else:
     247                # We haven't yet created the table to which this field
     248                # is related, so save it for later.
     249                #pr = pending_references.setdefault(f.rel.to, []).append((klass, f))
     250        #table_output.append(' '.join(field_output))
     251       
     252        # code added during refactoring
     253        has_pending_ref = False
     254        if f.rel:
     255            if f.rel.to not in models_already_seen:
     256                has_pending_ref = True
     257                   
     258       
     259    return field_output, has_pending_ref
     260
     261#------------------------------------------------------------------------------
     262
    131263def _get_sql_model_create(klass, models_already_seen=set()):
    132264    """
    133265    Get the SQL required to create a single model.
Back to Top