Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makemigrations in dev machine, without database instance

I am working in my dev machine. The code is tested during development in docker containers, because:

  • I have a nice docker-compose.yml
  • I want to develop in an environment as similar to the deploy environment as possible
  • I do not want to install any package system wide (specifically postgres): I only want in my development machine applications for development, not for testing or running applications.

Now I am trying to update my migrations:

» DJANGO_SECRET_KEY=xxx python manage.py makemigrations
....
django.db.utils.OperationalError: could not translate host name "postgres" to address: No address associated with hostname

Well, yes, of course, my host machine can not see the postgres container (only the running containers can see each other, as per docker compose architecture)

I could connect to the app container, make the migrations there, and retrieve the migrations to my development machine, but this does not seem a good solution.

My understanding is that the migrations are computed based on:

  • the currently stored migrations, in the development repo
  • the changes in the models, as compared to those migrations

I do not see why I need a database instance to make the migrations.

Can I make migrations without a connection to the database? How?

EDIT

Adding full traceback below. From what I can see, the connection to the database is attempted by the vanilla makemigrations command. Why is this the case?

I am running:

» python
Python 3.6.4 (default, Feb 22 2018, 09:26:37) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> django.__version__
'2.0.4'
>>> 


/myvenv/lib/python3.6/site-packages/psycopg2/__init__.py:144: UserWarning: The psycopg2 wheel package will be renamed from release 2.8; in order to keep installing from binary please use "pip install psycopg2-binary" instead. For details see: <http://initd.org/psycopg/docs/install.html#binary-install-from-pypi>.
  """)
Traceback (most recent call last):
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
    self.connect()
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/base/base.py", line 194, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/postgresql/base.py", line 168, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/myvenv/lib/python3.6/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not translate host name "postgres" to address: No address associated with hostname


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 24, in <module>
    execute_from_command_line(sys.argv)
  File "/myvenv/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line
    utility.execute()
  File "/myvenv/lib/python3.6/site-packages/django/core/management/__init__.py", line 365, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/myvenv/lib/python3.6/site-packages/django/core/management/base.py", line 288, in run_from_argv
    self.execute(*args, **cmd_options)
  File "/myvenv/lib/python3.6/site-packages/django/core/management/base.py", line 335, in execute
    output = self.handle(*args, **options)
  File "/myvenv/lib/python3.6/site-packages/django/core/management/commands/makemigrations.py", line 92, in handle
    loader.check_consistent_history(connection)
  File "/myvenv/lib/python3.6/site-packages/django/db/migrations/loader.py", line 275, in check_consistent_history
    applied = recorder.applied_migrations()
  File "/myvenv/lib/python3.6/site-packages/django/db/migrations/recorder.py", line 61, in applied_migrations
    if self.has_table():
  File "/myvenv/lib/python3.6/site-packages/django/db/migrations/recorder.py", line 44, in has_table
    return self.Migration._meta.db_table in self.connection.introspection.table_names(self.connection.cursor())
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/base/base.py", line 255, in cursor
    return self._cursor()
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/base/base.py", line 232, in _cursor
    self.ensure_connection()
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
    self.connect()
  File "/myvenv/lib/python3.6/site-packages/django/db/utils.py", line 89, in __exit__
    raise dj_exc_value.with_traceback(traceback) from exc_value
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/base/base.py", line 216, in ensure_connection
    self.connect()
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/base/base.py", line 194, in connect
    self.connection = self.get_new_connection(conn_params)
  File "/myvenv/lib/python3.6/site-packages/django/db/backends/postgresql/base.py", line 168, in get_new_connection
    connection = Database.connect(**conn_params)
  File "/myvenv/lib/python3.6/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
django.db.utils.OperationalError: could not translate host name "postgres" to address: No address associated with hostname

EDIT2

Running the migrations from the container works:

root@7dc4a3001a46:/code# python manage.py makemigrations
Migrations for 'something':
  proj/something/migrations/0001_initial.py
    - Create model Something

And now I have to get this migration out of the container, to my codebase? How cumbersome is that!? I can as well run the db on my host, or maybe allow for a connection to the containerized db from the dev host.

Still not clear to me why I need to have a db connection to prepare the migrations though.

like image 709
blueFast Avatar asked Apr 11 '18 15:04

blueFast


People also ask

When should you run Makemigrations?

When to run makemigrations. You'll want to run python manage.py makemigrations w henever you make a change to a model, even if it is updating the description on a field. Adding or updating functions inside of a model does not need a migration, but you can still run makemigrations just in case.

What is the difference between Makemigrations and migrate?

makemigrations is responsible for packaging up your model changes into individual migration files - analogous to commits - and migrate is responsible for applying those to your database.

How do you run Makemigrations?

Create or update a model. Run ./manage.py makemigrations <app_name> Run ./manage.py migrate to migrate everything or ./manage.py migrate <app_name> to migrate an individual app. Repeat as necessary.

Where are Django migrations stored?

Migrations are generated per app, and are stored in some_app/migrations . Even if you do not define migrations for your apps, there will usually be migrations that take place, since you (likely) included some apps defined by Django (and other third parties) in your INSTALLED_APPS , these have migrations as well.


1 Answers

The makemigrations command is trying to access the database to check the consistency of the migrations.

Ticket 26930 suggests that you can avoid the check by changing your settings to use the dummy backend.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.dummy',
    }
}
like image 79
Alasdair Avatar answered Sep 18 '22 20:09

Alasdair