Updating Models - django

Due to my little confidence with Django and my sheer horror at the thought of seriously messing up my beautiful project, I shall ask for proper advice/instructions here.
The database that my Django project is sitting on top of has been changed (a few field types have been changed) and my models are now out-of-sync. Funnily enough, my Django still works (God knows how) but I still want to update the models. How do I go about doing this the proper way. Thank you very much indeed in advance.
Marked as answered. My actual discover was:
./manage.py inspectdb > <file>
//Hands you all the tables from the database.
//Then you update the models accordingly.
SIMPLE! :)

It's probably a bit late, but you might want to take a look at South, which is a migrations system for Django.
The normal practice for your situation would be to run manage.py reset appname, where appname is the name of the app which contains the models you've changed. You'll obviously want to dump the data in the affected tables first (find out what tables are going to be affected by running manage.py sqlreset appname).
Finally, it's quite possible your site is still running happily because you've not restarted the webserver (I'm assuming you're talking about a production environment, the development server reloads most changes automatically).

If you've already made the changes to the live database, you can probably just change the models and restart your webserver.
As long as your Field names match between the database and the models you shouldn't have any issues.
That being said, it is a much better idea to use a migration tool like south (as Dominic suggested already)

Related

Creating migrations for a Django project that does not have any migrations already

I am working for a client with a 13 year old Django project. When they built the project migrations were not implemented so the project currently lacks migrations. I have tried creating migrations and then doing a datadump and loaddata into a new database to test them out. I am running into all sorts of errors and would like to start fresh.
So my question is this. What steps should I take to implement migrations in the project so that we can move forward using migrations? The django version has been updated to 3.0.5 and there are a number of GenericForeignKeys used, which might make this extra tricky. When creating the migrations originally I was told to use the fake tag but don't completely understand what this means.
Any help in the steps that I should take would be appreciated. For the sake of privacy/security for the client I don't want to just share a ton of their code but can share parts of it if it helps someone determine the steps that I should take.
For reference. After creating migration files originally and then trying the dumdata/loaddata commands I typically get an error saying that there are duplicate entries relating to contenttypes or duplicate entries for django_site domains. The client has domains set up depending on where in the world they are logging in from so the site "name" is unique but the "domain" is the same.
(1062, "Duplicate entry 'www.example.com' for key 'django_site.django_site_domain_a2e37b91_uniq'")
If you are talking about working on local, simply, delete all the migrations (except migrations/__init__.py.) and makemigrations again.
If you are on production, you are safe to use --fake once.
You are OK also to change the old migrations if you know how to do deal with migrations, and if it is few files.
I have answered a similar question here.

why does django not combine makemigrations and migrate commands?

I can think of three reasons why:
providing users with the flexibility on "when" to commit model changes
debugging modularity
perhaps resource consumption in larger
databases
However, it does seem that migrate always follows shortly after migration (tutorials/youtube videos).
so is there a philosophy behind this that I'm missing?
Ofcourse there are some reasons.
First of all, 'makemigrations' doesn't touch real DB, it just tells django how models(db scheme) have changed so you can see what's going on when you do 'migrate'.
and this makes django more safe.
This also provides to make default options for new fields or db changes..
Other reason is 'revert'.
If you want to roll-back db scehme with specific migrations, you can just tell django to roll back to specific migration file.
Another reason is 'reusable-app' principle.
If you create app with django and it could be reusable with no-db-interaction. It means if you deploy your app(or project, too!) to another project or server, it just needs 'migrations' files not real db.

TestCase To Detect DatabaseError: no such column

I recently added a new field to one of my models and forgot to add the appropriate column to the table in the database. I have test cases that test adding a new instance of this model and changing an existing instance. Neither of these test cases failed. Yet when I try to change an instance with the live site I get
DatabaseError no such column
I have made some attempts to detect this error from within a TestCase but no such luck.
Any help is greatly appreciated.
The problem is that you (I really, really hope) don't use your production database for testing with, so all that you could detect is that the column doesn't exist on your test database, which is (presumably) recreated from scratch based on your model definitions, not that the column is missing from your production database.
A better approach to this problem is to use a migration tool like South, and automate the deployment process so that migrations are run as new code is deployed.
This will only work for small(ish) sites - you might find naively running migrations causes pain if you've got a high-traffic site. If you're in that situation, you may find David Cramer's write-up on schema changes informative.
Unfortunetly, using syncdb command is not enough to update the database.
You can insert the fields manually with your database management system or use a solution like South.
Use following link it as very well explanation for your problem.
http://amionrails.wordpress.com/2013/11/17/django-databaseerror-no-such-column-error/

Is there a way to update the database with the changes in my models? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
update django database to reflect changes in existing models
I've used Django in the past and one of the frustrations I've had with it as an ORM tools is the inability to update an existing database with changes in the model. (Hibernate does this very well and makes things really easy for updating and heavily modifying a model and applying this to an existing database.) Is there a way to do this without wiping the database every time? It gets really old having to regenerate admin users and sites after every change in the model which I'd like to play with.
You will want to look into South. It provides a migrations system to migrate both schema changes as well as data from one version to the next.
It's quite powerful and the vast majority of changes can be handled simple by going
manage.py schemamigration --auto
manage.py migrate
The auto functionality does have it limits, and especially if the change is going to be run on a production system eventually you should check the code --auto generated to be sure it's doing what you expect.
South has a great guide to getting started and is well documented. You can find it at http://south.aeracode.org
No.
As the documentation of syncdb command states:
Syncdb will not alter existing tables
syncdb will only create tables
for models which have not yet been installed. It will never issue
ALTER TABLE statements to match changes made to a model class after
installation. Changes to model classes and database schemas often
involve some form of ambiguity and, in those cases, Django would have
to guess at the correct changes to make. There is a risk that critical
data would be lost in the process.
If you have made changes to a model and wish to alter the database
tables to match, use the sql command to display the new SQL structure
and compare that to your existing table schema to work out the
changes.
South seems to be how most people solve this problem, but a really quick and easy way to do this is to change the db directly through your database's interactive shell. Just launch your db shell (usually just dbshell) and manually alter, add, drop the fields and tables you need changed using your db syntax.
You may want to run manage.py sqlall appname to see the sql statements Django would run if it was creating the updated table, and then use those to alter the database tables and fields as required.
The Making Changes to a Database Schema section of the Django book has a few examples of how to do this: http://www.djangobook.com/en/1.0/chapter05/
I manually go into the database - whatever that may be for you: MySQL, PostgreSQL, etc. - to change database info, and then I adjust the models.py accordingly for reference. I know there is Django South, but I didn't want to bother with using another 3rd party application.

How to Manage Live Data in a Django Powered Project?

Noob here... :)
I'm working on a small and personal project that is already in "production", but development still is under way. In the last weeks I've managed to handle the updates in a hacky way. Usually, I make a dump of the (still small) database into json files, separed by app or sometimes by table, drop everything in the database, implement the model's changes in json level trough scripts, syncdb a new database, and put everything back on. I known, it's dumb, but I'm lacking knowledge of a better alternative. So, now that I'm borderline insane with this strategy I come to you guys.
I've looked into South, but I failed to understand how exactly is it's workflow regarding the Data migration (in opposition of it's schema migration that is obvious).
So, how do you guys do it?
Thanks in advance.
South creates python scripts. So you can use South to create schema migrations, and then change these scripts to include your own data migration.
If you just add models and fields you don't need to do this, you can just use plain South.