django-plotly-dash icon indicating copy to clipboard operation
django-plotly-dash copied to clipboard

The package generates Django migrations in the path of the pip package and not in the application migrations folder

Open erl987 opened this issue 3 years ago • 1 comments

Symptoms

When running the Django makemigrations command on a simple Django project that is just containing a simple Dash page derived from the examples available for django-plotly-dash, the migrations containing the database table for the internal communication of django-plotly-dash are generated in the migrations folder of the package and not in the migrations folder of the Django application.

Problem

This means that the migrations are not deployed into a Docker container running the Django app. The migrate command in this container thus complains about incomplete migrations.

Solutions?

Is there any way to avoid that the django-plotly-dash app is creating the migration files in the package folder? Copying the migration files manually from site-packages on the development machine into the site-packages on the container works but is no acceptable solution. The migrations need to be part of the codebase.

Details

This is the output of the makemigrations command on the Django project:

manage.py@django_dash_demo > makemigrations
bash -cl "/Users/user/opt/anaconda3/envs/django_dash_demo/bin/python /Applications/PyCharm.app/Contents/plugins/python/helpers/pycharm/django_manage.py makemigrations /Users/user/Documents/code/django_dash_demo"
Tracking file by folder pattern:  migrations
Migrations for 'django_plotly_dash':
  /Users/user/opt/anaconda3/envs/django_dash_demo/lib/python3.10/site-packages/django_plotly_dash/migrations/0003_auto_20220514_1220.py
    - Alter field id on dashapp
    - Alter field id on statelessapp

Note that the migrations are placed in the site-packages folder.

The migrations performed on the Django container will complain about being incomplete:

migrations_1  | Operations to perform:
migrations_1  |   Apply all migrations: admin, auth, contenttypes, django_plotly_dash, sessions
migrations_1  | Running migrations:
migrations_1  |   No migrations to apply.
migrations_1  |   Your models in app(s): 'django_plotly_dash' have changes that are not yet reflected in a migration, and so won't be applied.
migrations_1  |   Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

diagram_app.py

import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.express as px
from django_plotly_dash import DjangoDash

app = DjangoDash('PlotlyApp')

# assume you have a "long-form" data frame
# see https://plotly.com/python/px-arguments/ for more options
df = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})

fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

app.layout = html.Div(children=[
    html.H1(children='Hello Dash'),

    html.Div(children='''
        Dash: A web application framework for your data.
    '''),

    dcc.Graph(
        id='example-graph',
        figure=fig
    )
])

views.py:

# noinspection PyUnresolvedReferences
from django.shortcuts import render

# noinspection PyUnresolvedReferences
from . import diagram_app


def main(request):
    return render(request, 'diagram/index.html')

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    {% load plotly_dash %}
    <title>Title</title>
    {% plotly_header %}
</head>
<body>
<h1>Diagram</h1>

{% load plotly_dash %}

{% plotly_direct name="PlotlyApp" %}

{% plotly_footer %}
</body>
</html>

settings.py

from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-l(x8ue+or!t8ba+_c2y7z6)3kkg))hf@lrnqi%xhwz(81x9=jw'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []

# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'django_plotly_dash.apps.DjangoPlotlyDashConfig',
    'diagram'
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django_plotly_dash.middleware.BaseMiddleware'
]

ROOT_URLCONF = 'django_dash_demo.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates']
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 'django_dash_demo.wsgi.application'

# Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'db.sqlite3',
    }
}

# Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/

STATIC_URL = '/static/'

# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

X_FRAME_OPTIONS = 'SAMEORIGIN'

If necessary, I can provide the complete project. However, even this most simple demo project is having a lot of files because it is aggregating different technologies.

erl987 avatar May 14 '22 12:05 erl987

@erl987 What version are you running?

If I take the current release (git checkout of the master branch), create the environment, cd to the demo directory and then execute

./manage.py makemigrations

I do get a couple of warnings about auto-created primary keys (this is with Django v3.2.6) and the message No changes detected - in other words, the migrations within the app are complete.

Are you making changes to django-plotly-dash itself? If so you would need to work with the source code, not the installed package.

delsim avatar May 15 '22 03:05 delsim

I cannot reproduce the issue anymore in my application. Maybe due to changes to django-plotly-dash in the meanwhile.

erl987 avatar Jun 04 '23 15:06 erl987