I'm changing a field from CharField
to IntegerField
. The field name remains the same. The newly created field will be based off the old field. For example, if the old field was "L", it would have the number "1" instead. How can I accomplish this in the forwards()
function?
相关问题
- Django __str__ returned non-string (type NoneType)
- Django & Amazon SES SMTP. Cannot send email
- Django check user group permissions
- Django restrict pages to certain users
- UnicodeEncodeError with attach_file on EmailMessag
相关文章
- Profiling Django with PyCharm
- Why doesn't Django enforce my unique_together
- MultiValueDictKeyError in Django admin
- Django/Heroku: FATAL: too many connections for rol
- Django is sooo slow? errno 32 broken pipe? dcramer
- Django: Replacement for the default ManyToMany Wid
- Upgrading transaction.commit_manually() to Django
- UnicodeEncodeError when saving ImageField containi
The correct way to do it would be to break this into three migrations:
IntegerField
field.CharField
to theIntegerField
CharField
.A fourth one might be required if you want your newly added
IntegerField
to have the same name as the to-be-removedCharField
.Given a project state where the
IntegerField
is not yet added to you model file you should proceed by following these steps:IntegerField
to you model.datamigration
) for the application containing your model. In theforwards()
method of the newly createdDataMigration
class write down your logic to convert your data. Try to use theupdate
manager method instead of iterating overt all your database row if possible. If you declare your conversion logic using adict
(say{'L': 1, ...}
) it should be pretty easy to also implementbackwards()
at this time, given the operation is invertible. It's also a good exercise to make sure you've not overlooked an edged case inforwards()
-- it helped me quite a few times in the past.CharField
from your model.DROP
the now unused column.The fact that you broke this operation into three migrations instead of writing down your whole logic in a blank template have a couple advantages:
ADD
/DROP
logic have been automatically generated by South and you don't have to worry about introducing a typo in a database column.DataMigration.backwards()
for the conversion step you should be able to completely reverse the whole operation. This can be handy for testing purpose, if you need to rollback to a previous revision of your code and as safe net when updating a production code base.forwards()
method in this case) and an exception was raised during the data migration step (say aKeyError
because of an unhandled value in your conversiondict
). If you're using aORDBMS
that doesn't support transactional schema alteration you wouldn't be able to re-run you migration immediately after fixing the data-migration part, you'd have to manually drop the newly addedIntegerField
column yourself. Again, that's the kind of thing you don't want to deal with when migrating a production database.for the same situation me followed just 3 steps .
1) changed file type from CharField to IntegerField,
2) ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (col_name::integer); or
ALTER TABLE the_table ALTER COLUMN col_name TYPE integer USING (trim(col_name)::integer); # in case if you having whitespace in your Char or Text field. and if you having data's in your table, which should be string of integer.
3) Now apply migration.