def restore_indexes(self): db.start_transaction() for action_class, index in self.get_indexes(): if issubclass(action_class, AddIndex): # если поле уникальное, то индекс не надо - надо создать ограничение if len(index['fields']) == 1 and index['fields'][0].unique: pass else: db.create_index( index['model']._meta.db_table, [field.column for field in index['fields']]) # если поле одно и имеет тип varchar или text # то для postgresql должен быть еще один индекс с суффиксом _like # http://south.aeracode.org/ticket/1214 if len(index['fields']) == 1 and db._get_connection( ).vendor == 'postgresql': db_type = index['fields'][0].db_type( connection=db._get_connection()) if (db_type.startswith('varchar') or db_type == 'uuid'): self.create_index( db, index['model']._meta.db_table, [field.column for field in index['fields']], unique=not issubclass(action_class, AddIndex)) elif issubclass(action_class, AddUnique): db.create_unique(index['model']._meta.db_table, [field.column for field in index['fields']]) db.commit_transaction()
def forwards(self, orm): # remove duplicate renditions if db._get_connection().vendor == "mysql": db.execute( """ DELETE FROM wagtailimages_rendition WHERE CONCAT(image_id, '-', filter_id) IN ( SELECT CONCAT(image_id, '-', filter_id) FROM (SELECT * FROM wagtailimages_rendition) as x WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 ) AND focal_point_key IS NULL """ ) else: db.execute( """ DELETE FROM wagtailimages_rendition WHERE image_id || '-' || filter_id IN ( SELECT image_id || '-' || filter_id FROM wagtailimages_rendition WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 ) AND focal_point_key IS NULL """ ) # Changing field 'Rendition.focal_point_key' db.alter_column( "wagtailimages_rendition", "focal_point_key", self.gf("django.db.models.fields.CharField")(max_length=255, default=""), )
def forwards(self, orm): # Changing field 'InstitutionDetails.number_id' db.alter_column('edumanage_institutiondetails', 'number_id', self.gf('django.db.models.fields.PositiveIntegerField')(max_length=6, null=True, blank=True)) # Deleting field 'InstRealmMon.instid' db.delete_column('edumanage_instrealmmon', 'instid_id') # Renaming column for 'InstRealmMon.realm' to match new field type. db.rename_column('edumanage_instrealmmon', 'realm', 'realm_id') # Changing field 'InstRealmMon.realm' # WORKAROUND NEEDED # This migration breaks with PostgreSQL with: # ERROR: column "realm_id" cannot be cast automatically to type integer # HINT: Specify a USING expression to perform the conversion. # STATEMENT: ALTER TABLE "edumanage_instrealmmon" ALTER COLUMN "realm_id" TYPE integer, # ALTER COLUMN "realm_id" SET NOT NULL, ALTER COLUMN "realm_id" DROP DEFAULT; # This is a known problem: http://south.aeracode.org/ticket/484 # (PostgreSQL will not automatically convert and conversion must be provided with the USING clause) # Workaround: For PostgreSQL invoke a direct SQL statement amended with a USING clause to do the converion explicitly. # Credits: # * http://codeinthehole.com/writing/altering-postgres-table-columns-with-south/ # * http://stackoverflow.com/questions/13170570/change-type-of-varchar-field-to-integer-cannot-be-cast-automatically-to-type-i if ( db._get_connection().vendor == "postgresql" ): db.execute('ALTER TABLE "edumanage_instrealmmon" ALTER COLUMN "realm_id" TYPE integer USING (trim(realm_id)::integer), ALTER COLUMN "realm_id" SET NOT NULL, ALTER COLUMN "realm_id" DROP DEFAULT;') else: db.alter_column('edumanage_instrealmmon', 'realm_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['edumanage.InstRealm'])) # Adding index on 'InstRealmMon', fields ['realm'] db.create_index('edumanage_instrealmmon', ['realm_id']) # Changing field 'InstRealmMon.mon_type' db.alter_column('edumanage_instrealmmon', 'mon_type', self.gf('django.db.models.fields.CharField')(max_length=16))
def forwards(self, orm): conn = db._get_connection() tables = conn.introspection.table_names() for label, model in orm.models.items(): if label.split('.')[0] != self.complete_apps[0]: continue if model._meta.db_table in tables: db.delete_table(model._meta.db_table)
def forwards(self, orm): connection = db._get_connection() cursor = connection.cursor() try: cursor.execute('select partner_site_configuration from preferences_generalpreferences') connection.close() except: connection.close() db.add_column('preferences_generalpreferences', 'partner_site_configuration', self.gf('django.db.models.fields.TextField')(null=True, blank=True), keep_default=False)
def forwards(self, orm): connection = db._get_connection() cursor = connection.cursor() try: cursor.execute('select site_description from preferences_generalpreferences') connection.close() except: connection.close() db.add_column('preferences_generalpreferences', 'site_description', self.gf('django.db.models.fields.CharField')(max_length=512, null=True, blank=True), keep_default=False)
def forwards(self, orm): connection = db._get_connection() cursor = connection.cursor() try: cursor.execute('select exempted_ips from preferences_generalpreferences') connection.close() except: connection.close() db.add_column('preferences_generalpreferences', 'exempted_ips', self.gf('django.db.models.fields.TextField')(default=''), keep_default=False)
def _table_exists(self, name): """Determine whether the table exists.""" # HACK: Digging into South's db guts, in order to route around the # usual error handling. I feel dirty. There must be a better way. cursor = db._get_connection().cursor() try: cursor.execute("SELECT COUNT(*) FROM %s" % name) return True except DatabaseError: return False
def forwards(self, orm): connection = db._get_connection() cursor = connection.cursor() try: cursor.execute('select raw_field_order from %s' % db.quote_name('preferences_registrationpreferences')) connection.close() except: connection.close() # Adding field 'RegistrationPreferences.raw_field_order' db.add_column('preferences_registrationpreferences', 'raw_field_order', self.gf('django.db.models.fields.CharField')(default='{}', max_length=1024, blank=True), keep_default=False)
def houston_do_we_have_a_problem(table): "Checks if we're using MySQL + InnoDB" if not db.dry_run and db.backend_name == 'mysql': db_table = [db._get_connection().settings_dict['NAME'], table] ret = db.execute( "SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES " "where TABLE_SCHEMA = %s and TABLE_NAME = %s", db_table) assert len(ret) == 1 # There HAVE to be info about this table ! assert len(ret[0]) == 2 if ret[0][1] == 'InnoDB': print TERM_YELLOW, "!!!", '.'.join( db_table), "is InnoDB - using workarounds !!!", TERM_RESET return True return False
def houston_do_we_have_a_problem(table): "Checks if we're using MySQL + InnoDB" if not db.dry_run and db.backend_name == "mysql": db_table = [db._get_connection().settings_dict["NAME"], table] ret = db.execute( "SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES " "where TABLE_SCHEMA = %s and TABLE_NAME = %s", db_table, ) assert len(ret) == 1 # There HAVE to be info about this table ! assert len(ret[0]) == 2 if ret[0][1] == "InnoDB": print TERM_YELLOW, "!!!", ".".join(db_table), "is InnoDB - using workarounds !!!", TERM_RESET return True return False
def forwards(self, orm): connection = db._get_connection() table_names = connection.introspection.table_names() if 'socialregistration_openidprofile' in table_names: print "Doing idempotent OpenIDProfile transfer..." db.execute( "INSERT INTO openid_openidprofile (id, user_id, site_id, " "identity) (SELECT id, user_id, site_id, identity FROM " "socialregistration_openidprofile WHERE identity NOT IN " "(SELECT identity FROM openid_openidprofile))" ) db.execute( "SELECT setval('openid_openidprofile_id_seq', " "(SELECT MAX(id) + 1 FROM openid_openidprofile))" )
def forwards(self, orm): # Changing field 'InstitutionDetails.number_id' db.alter_column( 'edumanage_institutiondetails', 'number_id', self.gf('django.db.models.fields.PositiveIntegerField')( max_length=6, null=True, blank=True)) # Deleting field 'InstRealmMon.instid' db.delete_column('edumanage_instrealmmon', 'instid_id') # Renaming column for 'InstRealmMon.realm' to match new field type. db.rename_column('edumanage_instrealmmon', 'realm', 'realm_id') # Changing field 'InstRealmMon.realm' # WORKAROUND NEEDED # This migration breaks with PostgreSQL with: # ERROR: column "realm_id" cannot be cast automatically to type integer # HINT: Specify a USING expression to perform the conversion. # STATEMENT: ALTER TABLE "edumanage_instrealmmon" ALTER COLUMN "realm_id" TYPE integer, # ALTER COLUMN "realm_id" SET NOT NULL, ALTER COLUMN "realm_id" DROP DEFAULT; # This is a known problem: http://south.aeracode.org/ticket/484 # (PostgreSQL will not automatically convert and conversion must be provided with the USING clause) # Workaround: For PostgreSQL invoke a direct SQL statement amended with a USING clause to do the converion explicitly. # Credits: # * http://codeinthehole.com/writing/altering-postgres-table-columns-with-south/ # * http://stackoverflow.com/questions/13170570/change-type-of-varchar-field-to-integer-cannot-be-cast-automatically-to-type-i if (db._get_connection().vendor == "postgresql"): db.execute( 'ALTER TABLE "edumanage_instrealmmon" ALTER COLUMN "realm_id" TYPE integer USING (trim(realm_id)::integer),' ' ALTER COLUMN "realm_id" SET NOT NULL,' ' ALTER COLUMN "realm_id" DROP DEFAULT,' ' ADD CONSTRAINT "edumanage_i_realm_id_24cc89d4be4145e5_fk_edumanage_instrealm_id" FOREIGN KEY (realm_id) REFERENCES edumanage_instrealm(id) DEFERRABLE INITIALLY DEFERRED;' ) else: db.alter_column( 'edumanage_instrealmmon', 'realm_id', self.gf('django.db.models.fields.related.ForeignKey')( to=orm['edumanage.InstRealm'])) # Adding index on 'InstRealmMon', fields ['realm'] db.create_index('edumanage_instrealmmon', ['realm_id']) # Changing field 'InstRealmMon.mon_type' db.alter_column( 'edumanage_instrealmmon', 'mon_type', self.gf('django.db.models.fields.CharField')(max_length=16))
def forwards(self, orm): # remove duplicate renditions if db._get_connection().vendor == 'mysql': db.execute(""" DELETE FROM wagtailimages_rendition WHERE CONCAT(image_id, '-', filter_id) IN ( SELECT CONCAT(image_id, '-', filter_id) FROM (SELECT * FROM wagtailimages_rendition) as x WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 ) AND focal_point_key IS NULL """) else: db.execute(""" DELETE FROM wagtailimages_rendition WHERE image_id || '-' || filter_id IN ( SELECT image_id || '-' || filter_id FROM wagtailimages_rendition WHERE focal_point_key IS NULL GROUP BY image_id, filter_id HAVING COUNT(*) > 1 ) AND focal_point_key IS NULL """) # Changing field 'Rendition.focal_point_key' db.alter_column('wagtailimages_rendition', 'focal_point_key', self.gf('django.db.models.fields.CharField')(max_length=255, default=''))
def forwards(self, orm): # Adding model 'ListingPinned' db.create_table(u'foundry_listingpinned', ( (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('modelbase_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['jmbo.ModelBase'])), ('listing', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['foundry.Listing'])), ('position', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), )) db.send_create_signal(u'foundry', ['ListingPinned']) # Adding model 'ListingContent' db.create_table(u'foundry_listingcontent', ( (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), ('modelbase_obj', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['jmbo.ModelBase'])), ('listing', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['foundry.Listing'])), ('position', self.gf('django.db.models.fields.PositiveIntegerField')(default=0)), )) db.send_create_signal(u'foundry', ['ListingContent']) # Migrate data. Manual sql is required. if not db.dry_run: connection = db._get_connection() cursor = connection.cursor() for listing in orm.Listing.objects.all(): cursor.execute('select modelbase_id from %s where listing_id=%s' % (db.shorten_name(u'foundry_listing_content'), listing.pk)) for tu in cursor.fetchall(): orm.ListingContent.objects.create( modelbase_obj_id=tu[0], listing=listing, position=tu[0] ) cursor.execute('select modelbase_id from %s where listing_id=%s' % (db.shorten_name(u'foundry_listing_pinned'), listing.pk)) for tu in cursor.fetchall(): orm.ListingPinned.objects.create( modelbase_obj_id=tu[0], listing=listing, position=tu[0] ) # Do not delete tables. Paranoia. '''
def print_db_info(self): from django.conf import settings conn = db._get_connection().connection dbinfo = settings.DATABASES[db.db_alias] print 'Database: ' + conn.get_host_info() + ":" + str(conn.port) + ", db: " + dbinfo['NAME']
def db_table_exists(table_name): connection = db._get_connection() return table_name in connection.introspection.table_names()
def print_db_info(self): from django.conf import settings conn = db._get_connection().connection dbinfo = settings.DATABASES[db.db_alias] print 'Database: ' + conn.get_host_info() + ":" + str( conn.port) + ", db: " + dbinfo['NAME']