| 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 |
|---|