Reputation: 101
I need to delete fields from an existing django model that already have a few objects associated with it. Deleting the fields from models.py
gives me an error (obviously as there are table columns still associated with them). The data in body2
and body3
are not necessary for my app.
I have copied that data from those fields to the body
field. How would I go about deleting these fields without dropping the table entirely?
class Post(models.Model):
#some fields
body =EditorJsField(editorjs_config=editorjs_config)
body2 =EditorJsField(editorjs_config=editorjs_config)
body3 =EditorJsField(editorjs_config=editorjs_config)
I deleted body2
and body3
and ran migrations and when creating a new object, I get errors such as this.
django.db.utils.IntegrityError: null value in column "body2" of relation "second_posts" violates not-null constraint
DETAIL: Failing row contains (20, Wave | Deceptiveness, and unpredictability of nature, 2021-07-19 13:40:32.274815+00, 2021-07-19 13:40:32.274815+00, {"time":1626702023175,"blocks":[{"type":"paragraph","data":{"tex..., null, null, Just how unpredictable is nature? Nature is all around us, yet, ..., image/upload/v1626702035/dfaormaooiaa8felspqd.jpg, wave--deceptiveness-and-unpredictability-of-nature, #66c77c, l, 1, 1, 0).
This is the code that I'm using to save the sanitized data(after I've deleted those fields of course.)
post = Posts.objects.create(
body=form.cleaned_data.get('body'),
#
)
Upvotes: 3
Views: 15718
Reputation: 101
Since nobody seemed to have an answer, and since it looked like this error was an anomaly, I went the non-python way and ran SQL queries and dropped the columns. For those of you who ran into the same problem,
First, make Django aware of the changes
Delete the fields you want to be deleted and run migrations.
Before
class Post(models.Model):
#some fields
body =EditorJsField(editorjs_config=editorjs_config)
body2 =EditorJsField(editorjs_config=editorjs_config)
body3 =EditorJsField(editorjs_config=editorjs_config)
After
class Post(models.Model):
#some fields
body =EditorJsField(editorjs_config=editorjs_config)
Command Prompt
python manage.py makemigrations
python manage.py migrate
Drop the columns using SQL queries
First connect to your database(I used postgres). The name of the table should be something like appname_model
. My app was called "Second" and the model was Post. So, the table was called second_post
.
See if the columns still persist after the migrations using,
In the SQL command prompt
/d second_post
This should give you a nice diagram of the database with all the columns listed on the left side. To drop those columns, type,
ALTER TABLE second_post DROP COLUMN body2;
ALTER TABLE second_post DROP COLUMN body3;
After entering each query, the prompt should return a string ALTER TABLE
if successful.
Upvotes: 6
Reputation: 20569
If you want to drop the data completely, you need to create a Django migration (using ./manage.py makemigrations
preferably) that will remove those columns from the database.
Alternatively, if you want to play safe and persist the old data, you can first make those fields as nullable, then create migrations for them and at the end either just don't use them anymore or remove those columns from the model, but don't reflect it in migrations (you'll need to fake the removal of those columns in migrations though if you'll ever need to run another migration in this app).
Upvotes: 1