Rails remove table - ruby-on-rails-4

Using rails 4 and generated a table and then did a rake db:migrate to add the table to my schema.rb. However, I have destroyed the table, which removed its model and views but it still seems to appear in my schema.rb file, which is due to the migration. Is it safe to simply remove the lines from my codebase in sublime or is there a particular method for handling this in terminal.

You should create another migration that will revert the effects of previous one. That is, on up it will drop that table.
Of course, if you don't have existing production installation to care about, then you can just delete the original migration file, recreate database and pretend that table never existed.
If you do have existing database with important data, then full recreation is not an option, write the reverse migration.

Related

Django on_delete=CASCADE not working, can't delete parent row using raw SQL [duplicate]

I'm using Django 1.3 with the MySQL 5.5 database backend. My assumption was that Django by default emulates the ON DELETE CASCADE effect for related objects when building the database via syncdb. However, inspecting the database reveals that the ON DELETE property is in fact set to "RESTRICT". Is this a bug? As I'm unable to delete related records I keep getting the IntegrityError message in the djang-admin when deleting an object that has a related object.
Thanks
Django emulates ON DELETE CASCADE in Python -- that's why is doesnt need it set on the database tables. In fact, setting RESTRICT might even make sense, since it means that you can't accidentally delete any related objects without being warned about it in the admin.
In your case, it seems like you may have foreign key constraints set up that Django doesn't know about -- or possibly you are trying to delete through raw SQL; I can't tell from your question.
If the issue is that you can't delete from the admin, or from the ORM, then you need to make sure that your models are defined correctly. django will take care of collecting the related objects and performing the cascade itself.
If the issue is that deletes don't work from raw SQL, then you will either need to manually delete the related objects first, or relax the SQL constraint -- in that case, changing it to cascade may be the right solution.
It would seem that Django 1.3.1 for some reason fails to apply the ON DELETE CASCADE property to the table. It could possibly have something to do with the MySQL-python 1.2.3 interface running on Windows. The only other way to resolve this issue is via custom SQL.
Django does cascade by default. I'm not really sure why you're getting an ON DELETE RESTRICT. Django 1.3 does let you select alternate ON DELETE procedures (using the on_delete kwarg when defining a field), and it's possible that if you inherited the codebase, someone might have done that previously and then removed it from the code, but neglected to update the database.
I would suggest altering the column manually to set it back to ON DELETE CASCADE. And simply move on from there. Like I said, this is something that the developer has to tell Django not to do; it cascades by default.

Django south datamigrations not running post saves

I am using django south data-migrations to update data in new tables after schema-migrations that create some new tables. I have written some post-save methods on existing tables to update data on newly created tables. For this, I am using data-migrations and in forward method, I am saving existing table rows so that in post-saves, new tables will get data populated.
However, the post saves dont run after running the data migrations.
One way is to call the post-save function directly from forward method in datamigrations. But south documentations recommends that you should use orm objects to freeze the state. But in post-save methods, we will be using these models normally. Another way is to copy same code in migration but that way, everytime I make changes in post-save method, I also need to update code in datamigration forward method.
What is the best way to achieve this?
Migration files are just Python modules. You can always import code from other parts of the project hence reusing logic.
That however is a slippery slope because:
Lets say you have a migration which migrates database from state X to state Y (and backwards). Now lets say this migration reuses some code from foo.py. Now after some time you need to change your db state from state Y to state Z. If again you reuse some logic from foo.py, then you can no longer execute your first migration on a fresh db since some logic is shared between 2 migrations.
If you leave the migration code completely independent, it will make it much easier to maintain many migrations in a long run, even though it can introduce some code duplication.

South: Why creating a new empty migration when pulling in other developer's model changes?

Below is extracted from the section of the official South documentation on Team Workflow,
The second thing to note is that, when you pull in someone else’s model changes complete with their own migration, you’ll need to make a new empty migration that has the changes from both branches of development frozen in (if you’ve used mercurial, this is equivalent to a merge commit).
I don't see why the need for creating a new empty migration in this case. Shouldn't the developer just run ./manage.py migrate after pulling in the model changes (and the corresponding migrations) from others? What am I missing here?
I believe what that means is that if both branches have changes to the same model, then its better to merge the code and re-create a single migration script for those changes. This is because if branch1 has a 0006 migration script and branch2 has another 0006 migration script (you know how south names them sequentially...) then you can't correctly auto merge them since they are actually different files.
Hence you'd need to merge code changes and then re-create a migration script for the merged branch.
We had a problem related to this piece. Say we have a model:
class Article(Model):
title = CharField()
Developer 1 adds a field to it, say, author, on his branch (migration freezes title, author)
Developer 2 adds a field date_published, on his branch (migration freezes title, date_published)
Then somebody merges two branches. What they get is two migrations where one doesn't know about date_published and the other one haven't seen field author.
What this could lead to is south trying to add author or date_published field (whatever migration was added last) next time you create auto migrations, because it simply doesn't know the 100% correct db state, it's not frozen inside migrations.

Django -- add model to database without losing data

I have a simple Django website (just a form, really) which asks a few questions and saves the data in a SQL database using Model.save(). Pretty simple. I want to add a model to do page counting, though -- it'll just be a single object with a field that gets incremented each time the page's view function is called.
Now, I know little to nothing about SQL. I imagine this is not terribly difficult to do, but I would like to avoid losing or breaking all my data because of a slight misunderstanding of how the database works. So how can I go about doing this? I've heard of some third-party apps that will implement such functionality, but I'd like to do it myself just for learning purposes.
I don't understand why your existing data would be affected at all. You're talking about adding a completely new table to the database, which is supported within Django by simply running manage.py syncdb. The case where that doesn't work is when you're modifying existing tables, but you're not doing that here.
I must say though that learning and using South would be of benefit in any case. It's good practice to have a tool that can maintain your model tables.
(Plus, of course, you would never lose any data, because your database is backed up, right? Right?)
Since you're adding new model, you can just run syncdb and it will create new table for your model. If you were to change existing model, then you'd need to manually update database schema using "ALTER TABLE" statements or use South instead.

Django not setting MySQL ON DELETE = CASCADE

I'm using Django 1.3 with the MySQL 5.5 database backend. My assumption was that Django by default emulates the ON DELETE CASCADE effect for related objects when building the database via syncdb. However, inspecting the database reveals that the ON DELETE property is in fact set to "RESTRICT". Is this a bug? As I'm unable to delete related records I keep getting the IntegrityError message in the djang-admin when deleting an object that has a related object.
Thanks
Django emulates ON DELETE CASCADE in Python -- that's why is doesnt need it set on the database tables. In fact, setting RESTRICT might even make sense, since it means that you can't accidentally delete any related objects without being warned about it in the admin.
In your case, it seems like you may have foreign key constraints set up that Django doesn't know about -- or possibly you are trying to delete through raw SQL; I can't tell from your question.
If the issue is that you can't delete from the admin, or from the ORM, then you need to make sure that your models are defined correctly. django will take care of collecting the related objects and performing the cascade itself.
If the issue is that deletes don't work from raw SQL, then you will either need to manually delete the related objects first, or relax the SQL constraint -- in that case, changing it to cascade may be the right solution.
It would seem that Django 1.3.1 for some reason fails to apply the ON DELETE CASCADE property to the table. It could possibly have something to do with the MySQL-python 1.2.3 interface running on Windows. The only other way to resolve this issue is via custom SQL.
Django does cascade by default. I'm not really sure why you're getting an ON DELETE RESTRICT. Django 1.3 does let you select alternate ON DELETE procedures (using the on_delete kwarg when defining a field), and it's possible that if you inherited the codebase, someone might have done that previously and then removed it from the code, but neglected to update the database.
I would suggest altering the column manually to set it back to ON DELETE CASCADE. And simply move on from there. Like I said, this is something that the developer has to tell Django not to do; it cascades by default.