If I'm going to add another SQLAlchemy model, does it automatically be added to my database? Do I need to run some commands for it to be added or checked?
It will only be added if you run the db.create_all() command again.
If your model is going to be changing frequently it might be worth getting to grips with something like Flask-Migrate which can handle database migrations really nicely.
Related
I am working on an existing Django project that contains migration code like:
someFluffyModel.objects.all().delete()
or
someModel = SomeModel(....)
someModel.save()
Now wherever there is such code and newer migrations change the schema that reflect the current version of the model, there is an issue in applying migrations from scratch.
As I understand the reason is that the model used in the migration doesn't reflect the model used in the migration at that point in time. As I have found fixtures can help in loading data but how about deletion?
Is the preferred way to manually delete data from the database?
Sorry forgot to answer my own old question it's been years now but just in case anybody is curious in your migrations you should always be using historical models. The reason is that you get the model at a point in time(reconstructed incrementally base on schema migrations).
def forwards_func(apps, schema_editor):
# We get the model from the versioned app registry;
# if we directly import it, it'll be the wrong version
Country = apps.get_model("myapp", "Country")
This way if you try to re-run your migrations at some point in the future with model schema x'' old migrations will be run using x' and x depending on their dependencies.
Avoid importing models to your migrations directly at any cost.
It is always important to be able to rer-run you migrations since that allows you to migrate forwards backwards between your environments roll back faulty deployments and above all run your tests. If you are doing it wrong your tests will fail at some point when you'll get to schema x' and you'll have to follow the correct approach mentioned above to fix them.
Thanks to #Daniel Roseman for giving me some pointers that day.
I am having trouble running the django migrations on a new database because of the get_or_create() function in a form.
form.py
class EmployeeForm(...):
# Make sure that we have a directory before initializing the form
default_upload_directory = Directory.objects.get_or_create(name='Employee', parent=None)[0]
This is the important part of a custom form I wrote. It will link the Employee's uploaded files to a default directory. Everything works fine except for the migration. When I run it on a new database it will complain with django.db.utils.OperationalError: no such table: filemanager_directory. It also happens if I use a standard objects.get(..) to access the Directory object.
I am not sure how to solve this. Obviously the table does not exist, yet. On an existing database with the tables already in place everything works fine.
EDIT: The migrations I am trying to run are not related to this app. Furthermore, as a workaround, you can comment out the line, run the migrations and reactivate it... But this is not a neat solution...
This is, quite simply, not a thing you should do. You shouldn't run any kind of database access in any code that runs at import time, which this does.
There should never be a need to do this in any case. If your goal is to ensure an object exists when the form is instantiated, put it in the __init__ method.
But you should also reflect that ensuring that database objects exist is the job of migrations in the first place. Write a data migration with a RunPython method to do this.
If one is using Django, what happens with changes made directly to the database (in my case postgres) through either pgadmin or psql?
How are such changes handled by migrations? Do they take precedence over what the ORM thinks the state of affairs is, or does Django override them and impose it's own sense of change history?
Finally, how are any of these issues effected, or avoided, by git, if at all?
Thanks.
You can exclude a model completely from the django migrations, and then you are responsible to adjust the schema to the django code (or the django code to the existing schema):
class SomeModel(models.Model):
class Meta:
managed = False
db_table = "some_table_name"
name = models.Fields....
Note that you can't have it both ways, so migrations are preferred when possible. You can always define a custom SQL migration, that will save the need for external changes. However, sometimes you do need to handle the schema elsewhere instead of migrations, and then use managed=False
The migrations system does not look at your current schema at all. It builds up its picture from the graph of previous migrations and the current state of models.py. That means that if you make changes to the schema from outside this system, it will be out of sync; if you then make the equivalent change in models.py and create migrations, when you run them you will probably get an error.
For that reason, you should avoid doing this. If it's done already, you could apply the conflicting migration in fake mode, which simply marks it as done without actually running the code against the database. But it's simpler to do everything via migrations in the first place.
git has no impact on this at all, other than to reiterate that migrations are code, and should be added to your git repo.
I created a table before I code the Django app and now I merged both the app and the table with following command python manage.py inspectdb > models.py. However after some while I really need to change the value type of one of the column. Is it enough to chage it through the model file or do I need some additional steps?
If you change a field in a Django model, Django itself doesn't know how to update your database accordingly (syncdb only add tables from new models).
You have two options:
manually create your database tables;
use a migration tool like South that detects and generates migration files from changes made to your models;
I recommend the second option as it's programmatic, more error-proof and makes your life easier when you need to go back and forth between database schemas.
There is an easy way to do this. (in Django 2)
After making the necessary changes to the model.py file of your app, run command:
python manage.py makemigrations - This will generate a new file in migration folder of your app.
python manage.py migrate - This will apply those edits on actual databse.
To check if the changes have been applied, run command : .schema <tablename> in your terminal, after entering the sqlite command-line program.
I have just created my first Django app which uses a Postgres database... which was working until I broke it by trying to rename it. I only have placeholder data in the database, and so I am not concerned about database migration, I simply want to get my app working again and with an empty database is just fine. I found this question on here: How to change the name of a Django app? which lays out the steps involved in re-naming a Django app. I have done the first two which are to 1) Rename the folder found in the project root and 2) change any references to the app in its dependencies, i.e. the app's views, the urls.py and settings.py files.
As a newbie to Django and programming, the third step is not clear to me. The instructions were to:
"Edit the database table django_content_type with the following command: UPDATE django_content_type SET app_label='' WHERE app_label='' Note: for renaming models, you'll need to change django_content_type.name"
So I have two very specific questions:
1) Where/how do I edit the database table? As in, where do I physically type this command? And/or how do I change the "django_content_type.name"?
2) I have already pushed my project to Heroku and have a working version of my app there. What will I need to do on the Heroku side to handle this change?
Thanks in advance for your patience!
You need to go to the database table manually, or use dbshell.
> ./manage.py dbshell #opens the database command line.
This places you in the command line
$> UPDATE django_content_type SET app_label='<new_label>' WHERE app_label='<old_label>'
$> <ctrl>-D
This is make you all set. You dont need to do anything else on the heroku side apart from this change.