makemigrations, migrate, and existing databases

Hi,
I created a new application, and the first time I ran makemigrations I did not use any option ( like --dry-run or --empty), however :

  • no directory migration created ;
  • the method app.models is not available.
  • when I ran “migrate” then django creatred properly its table into the data base.

Cannot understand where what could be wrong.
I have tried the --check option (django 4.0 ) , but it replies that there are no changes in app. Sure, it is right, but doesn’t help.

An idea of what to do ?

May be there is a link : I use postgresql, and I defined 2 dictionaries :

DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.postgresql_psycopg2’,
‘NAME’: ‘fermel’,
‘OPTIONS’: {
‘options’: ‘-c search_path=commun,public’,
},
‘USER’: ‘me’,
‘PASSWORD’: ‘pass’,
‘HOST’: ‘vps’,
‘PORT’: ‘5434’,
},
‘fermel’: {
‘NAME’: ‘fermel’,
‘ENGINE’: ‘django.db.backends.postgresql’,
‘OPTIONS’: {
‘options’: ‘-c search_path=ferme’,
},
‘USER’: ‘me’,
‘PASSWORD’: 'pass,
‘HOST’: ‘vps’,
‘PORT’: ‘5434’,
}
}

=== The errors ===


> python manage.py makemigrations --check fermel                                                                                        09/05/2023 08:57:51 
No changes detected in app 'fermel'
~/> python manage.py migrate fermel                                                                                                       09/05/2023 09:01:09 
CommandError: App 'fermel' does not have migrations.

The fermel in your makemigrations statement is a reference to an app, not the database.

Do you have an app named fermel? What are the contents of its models.py file?

What are you expecting to see happen that isn’t happening? I’m having a difficult time understanding what the problem is here that you’re trying to describe.

Sorry for not being clear.
Yes I did an app called fermel. the support of this application is a database fermel as well.
When I had done the inspectdb process, I got 2 files with the classes related to all tables ( an extract of one of the files here : bin.infini )
Great.
But, then I did the migrate and mkmigrations as I mentioned. Fine. But it does not do the process properly since there is not any file created in migration directory. And beside this if I go to the shell then the classe fermel gets subclasses apps and settings but no models. This is my problem.

More precisely, “migrate” did the job because I have into the database, tables like

commun | auth_group                 | table | 
 commun | auth_group_permissions     | table | 
 commun | auth_permission            | table | 
 commun | auth_user                  | table | 
 commun | auth_user_groups           | table | 
 commun | auth_user_user_permissions | table |

SO I think it’s only the makemigration that did not work, but without error message, to link the class fermel to its models, for some reason that I do not understand.

Tanks.

What are the contents of the models.py file in your fermel app?

It is done automatically, I did not change anything beside the “managed = true”. I had put an extract here : bin.infini

Please post your INSTALLED_APPS setting here.

Something is causing your models.py file not to be seen by Django, because this line is syntactically wrong:

You need to use True, not true. If Django were trying to read that file, then you would get an error message in your makemigrations command.
(Actually, you don’t need that at all, since that’s the default. You only need to specify it if you want it to be False.)

Keep in mind as well that inspectdb is a starting point and not an ending point. You should review that file carefully to ensure it has accurately represented the data you’re trying to use.

You don’t typically need to use --check when running makemigrations. It’s really only used when writing scripts or other code that will run makemigrations for you.

(Also, for future reference, please post requested code here and not in some external site. When posting code here, enclose it between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```. This forces the forum software to keep your code properly formatted.)

Thanks.

So I had restarted again from 0, and this time I left the managed set to False, and checked the points mentioned at the top of the self generated files of models.

This did not changes much the behaviour. Is their a way to get an error message that can help me know what’s wrong in the models files for Django to process it ?
For instance, the only message I get is : No changes detected in app ‘fermel’
Otherwise I will proceed by elimination with only on class (on table) and then go on.

  1. Verify that your fermel/migrations directory is empty.
  2. Post the command and output of manage showmigrations
  3. Run the command manage makemigrations -v 3 fermel and post the entire output.

You show that you’re using multiple databases. Are you using any routers for this? If so, post the code for them here.
Which schema was inspected when you ran inspectdb?

Note: If these tables already exist, why are you looking for a migration file to be created? The models already match the database. What are you hoping to achieve by this?

My INSTALLED_APPS :

INSTALLED_APPS = [
    'fermel.apps.Scege_agriConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
  1. There is no migration directory. as I understood from the tutorial Coup d’œil sur Django | Documentation de Django | Django that I followed, this directory is done automatically. But it did not.
  2. manage showmigrations
    Interesting command that I didn’t know about… here is the result :

admin>
0001_initial
0002_logentry_remove_auto_add
0003_logentry_add_action_flag_choices
auth
0001_initial
0002_alter_permission_name_max_length
0003_alter_user_email_max_length
0004_alter_user_username_opts
0005_alter_user_last_login_null
0006_require_contenttypes_0002
0007_alter_validators_add_error_messages
0008_alter_user_username_max_length
0009_alter_user_last_name_max_length
0010_alter_group_name_max_length
0011_update_proxy_permissions
0012_alter_user_first_name_max_length
contenttypes
0001_initial
0002_remove_content_type_name
sessions
0001_initial

python ./manage.py makemigrations -v 3 fermel
No changes detected in app ‘fermel’

You show that you’re using multiple databases. Are you using any routers for this? If so, post the code for them here.
No only one database, but I had split into :

  • default for schemas «commun» and «public»
  • fermel for schema «ferme» (I might call it ferme instead of fermel).

Which schema was inspected when you ran inspectdb?

All these 3, I did the following (using bash in GNU/Linux) from withing the directory «fermel»:

python ./manage.py inspectdb --database=fermel > ./modeles_fermel.py ; python ./manage.py inspectdb --database=default > ./modeles_fermel_defaut.py

Note: If these tables already exist, why are you looking for a migration file to be created? The models already match the database. What are you hoping to achieve by this?

Your question rise in my mind that I might not understood the basis principle… Reading the tutorial I already mentioned here above, I understood that making these migrations make django set up the models to be able to access the tables of the database and work (update data, read data, etc…). Do you mean it is possible to do so without migrations ? How ?
Actually into the shell I do not have access to fermel.models, so how could I read for example the table of the database in the schema commun, say femel.commun.fournisseurs ?

By routers did you mean this https://docs.djangoproject.com/fr/4.2/topics/db/multi-db/#allow_migrate ?

I probably might use it, cause I have the feeling that it would be pertinent in my case. Do you think so ?

That link is not a tutorial. From the second paragraph on that page:

Le but de ce document est de vous donner assez de détails techniques pour comprendre comment fonctionne Django, mais il n’a pas pour but d’être un didacticiel ou une référence – mais nous avons cela aussi !

If you need a tutorial, you should work your way through the Official Django Tutorial.

Just to make something clear here. Your models file must be named models.py, not modeles_fermel.py or any other variation. (That’s covered in the official Django tutorial linked to above.)

Again, that page is not a tutorial or a reference. Do not rely upon it in that context. It gives you some understanding of what’s going on, but it’s not complete.

That is not correct. See the docs at Migrations | Django documentation | Django

I suggest at this point you take a step back and work your way through the official Django tutorial. It’s going to answer a lot of questions you’re having about this.

All right. Sorry for your wasted time. It was convenient for to work on that non tutorial cause in french, and sometimes I do not really understand the meaning of some sentences on the other one (that I have tried to read already).

Don’t worry about it! You have not wasted any time. We’re here to help get you started - in whatever direction that happens to take you.

Are you working from the French version? Écriture de votre première application Django, 1ère partie | Documentation de Django | Django

If there are issues with the translation, I know the French-language team would love to hear about them. If you’re fine with the language but are having difficulties with the meaning, we can continue to try and help you here.

Yes.

If there are issues with the translation, I know the French-language team would love to hear about them. If you’re fine with the language but are having difficulties with the meaning, we can continue to try and help you here.

I will redo both, french and english. If something is not clear for me, I will note it for the Fench team. In this way, we may have something perfect for everyone. I’m sure the french team dii a really good job, but I’m not a developper and this might make harder my ability to understand the things.

Honestly, it is quiet clear when you want to work with a new project, setting up new database. But starting with an existing database, is not clear.

Where can I suggest something to the french translation team ?

I will admit, the docs are more structured toward creating a new database - that’s more frequently the case.

However, once you understand what those tools (makemigrations and migrate) actually do, you realize that working with existing data only means you aren’t doing some things that are needed when creating a new database.

Your first point of contact may be the “Internals” / “Internationalizion” forum section here - make sure you include the word “French” in the subject line of whatever issue you raise.

Or, the ticket system also says this:

This is typically the kind of sentences wihich are not clear for me… :sweat_smile:

Do you mean that to use an existing database, which doesn’t need the same operations than creating one, therefore it is useless to use (makemigrations and migrate) ?

Yes this what I understood from your answers yesterday. But here there is 3 points :

  1. I did not see in the doc : Do not use makemigrations and migrate to work with existing data. Instead follow this link where it is explained what to do in this case.
  2. Since the whole documentation is oriented by creating something new, then…
  3. You could, I did, came to the point that : creating a new database is done with makemigrations and migrate + no special mention about existing one = use makemigrations and migrate for existing database as well because at some point, creating a new one or not, django need to set up the models of your project and in both cases it is done with these tools (makemigrations and migrate).

So, I would suggest, in English like other languages, even if I am the only one whom did the mistake, that for existing data, we should follow another way.

Exactly, when you use an existing database, you do not need to create it (it already exists), so it is useless to use makemigrations and migrate:

  • makemigrations “translate” your python models description (from models.py) into “equivalents” of sql statements for creation (or modifications in case of model updates) of tables. So, you do not need such translation as your tables already exist, and you explicitly tell django not to so so by setting managed=False
  • migrate applies the sql statements corresponding to a migration to effectively create (or update) database tables. But again, you do not want this as everything already exists in your database.

This is where you misunderstood how it works. What sets up the model (i.e. what make django able to transition from the python world to your databse world, and vice-versa) is the description of your models in models.py (either written from scratch for non pre-existing database or maybe generated using inspectdb for a legacy database), and nothing else.
makemigrations / migrate is only there to set up your database (not django) so that it correspond to what your primarily described using python in your models.py. You can think about it as the exact inverse of inspectdb.

For documentation reference about using legacy database, see Intégration de Django avec une base de données existante | Documentation de Django | Django.

The key sentence here is:

C’est-à-dire que la présence de managed = False dans la classe Meta des modèles indique à Django de ne pas piloter la création de la table correspondante, ni sa modification ou sa destruction.

It explicitly says that when using a model with managed=False, you tell Django not to create, update or delete the database, which is what makemigrations/migrate do ; so, this equivalent as saying (even if not mentioned as is):

C’est-à-dire que la présence de managed = False dans la classe Meta des modèles indique à Django de ne pas gérer de migrations pour ce modéle.

See also Migrations | Documentation de Django | Django where the introduction states what the migrations stand for (“propage des modifications que vous apportez à des modèles (ajout d’un champ, suppression d’un modèle, etc.)”) which corresponds to the equivalency I made above

No, that’s not quite accurate.

Is it “useless” to use those? No.

However, you will get different results from those commands.

Correct, because that’s not the recommendation.

You should be using it regardless.

However, what you should not be worried about is the absence of a migration file if there is no difference between your models and the existing data.

Again - this becomes a lot more clear once you understand what those commands do.

Except that’s not what makemigrations does.

And migrate just processes the migration files that have been created (either manually or automatically).

Yes, sorry for my imprecision. managed=False does not prevent django from generating migration files, it just prevent migrate from effectively applying the migrations (as explained here Options Meta des modèles | Documentation de Django | Django).