Reputation: 2958
I have an app deployed on pythonanywhere which runs fine. Problem is that when I want to run test django, my test database settings is completely ignored. Each time I run test I get the following message.though.
Creating test database for alias 'default'...
Got an error creating the test database: (1044, "Access denied for user 'funnshopp'@'%' to database 'test_funnshopp$funn'")
Database name for the app is funnshopp$funn
. It can be seen that django somehow always tries to create the test database by appending test_
to the database name. Never minding what I have in DATABASES
settings
Below is my full settings file ( Test runs fine on my PC and I am using Django 2.0
, though I started the project with Django 1.11
)
"""
Django settings for funnshopp project.
Generated by 'django-admin startproject' using Django 1.11.7.
For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""
import os
from django.urls import reverse_lazy
from django.core.exceptions import ImproperlyConfigured
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
def get_env_variable(var_name):
"""Get the environment variable or return exception"""
try:
return os.environ[var_name]
except KeyError:
error_msg = "Set the {} environment variable".format(var_name)
raise ImproperlyConfigured(error_msg)
ENV_ROLE = get_env_variable("ENV_ROLE")
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = get_env_variable("SECRET_KEY")
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
FUNN_PASS = False
if ENV_ROLE == "development":
DEBUG = True
FUNN_PASS = get_env_variable('FUNN_PASS')
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'asset',
'debit',
'communication',
'establishment',
'credit',
'personnel',
'relation',
'debug_toolbar',
'captcha',
'guardian',
'rules',
'coverage',
'django_extensions',
'pure_pagination',
'sorl.thumbnail',
'django_addanother',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'guardian.backends.ObjectPermissionBackend',
'rules.permissions.ObjectPermissionBackend',
)
MIDDLEWARE = [
'debug_toolbar.middleware.DebugToolbarMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'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',
]
ROOT_URLCONF = 'funnshopp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(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 = 'funnshopp.wsgi.application'
INTERNAL_IPS = ('127.0.0.1', 'localhost')
DEBUG_TOOLBAR_PANELS = [
'debug_toolbar.panels.versions.VersionsPanel',
'debug_toolbar.panels.timer.TimerPanel',
'debug_toolbar.panels.settings.SettingsPanel',
'debug_toolbar.panels.headers.HeadersPanel',
'debug_toolbar.panels.request.RequestPanel',
'debug_toolbar.panels.sql.SQLPanel',
'debug_toolbar.panels.staticfiles.StaticFilesPanel',
'debug_toolbar.panels.templates.TemplatesPanel',
'debug_toolbar.panels.cache.CachePanel',
'debug_toolbar.panels.signals.SignalsPanel',
'debug_toolbar.panels.logging.LoggingPanel',
'debug_toolbar.panels.redirects.RedirectsPanel',
]
GOOGLE_RECAPTCHA_SITE_KEY = get_env_variable("GOOGLE_RECAPTCHA_SITE_KEY")
GOOGLE_RECAPTCHA_SECRET_KEY = get_env_variable("GOOGLE_RECAPTCHA_SECRET_KEY")
LOGIN_REDIRECT_URL = reverse_lazy('personnel:dashboard')
LOGIN_URL = reverse_lazy('personnel:login')
LOGOUT_URL = reverse_lazy('personnel:logout')
if ENV_ROLE == "development":
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
else:
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_USE_TLS = True
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = '***@gmail.com'
EMAIL_HOST_PASSWORD = '*******'
DEFAULT_FROM_EMAIL = '***@gmail.com'
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
DEPLOYMENT_PLATFORM = get_env_variable("DEPLOYMENT_PLATFORM")
if DEPLOYMENT_PLATFORM == "heroku-plus-local":
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'funn',
'USER': 'postgres',
'PASSWORD': get_env_variable('FUNN_PASS'),
'HOST': 'localhost',
'PORT': 5432
}
}
else: # DEPLOYMENT_PLATFORM == "pythonanywhere"
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'USER': 'funnshopp',
'NAME': 'funnshopp$funn',
'PASSWORD': get_env_variable('FUNN_PASS'),
'HOST': 'funnshopp.mysql.pythonanywhere-services.com',
'TEST':{
'ENGINE': 'django.db.backends.sqlite3', # for sqlite3
'NAME':'test.db',
# 'ENGINE': 'django.db.backends.mysql',
# 'NAME':'funnshopp$test_default'
},
},
}
# Password validation
# https://docs.djangoproject.com/en/1.11/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/1.11/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Africa/Lagos'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = 'staticfiles'
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
AUTH_USER_MODEL = 'personnel.Person'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
import django_heroku
django_heroku.settings(locals())
Below is the result of pip freeze
alabaster==0.7.10
Babel==2.5.1
beautifulsoup4==4.6.0
certifi==2017.11.5
chardet==3.0.4
colorama==0.3.9
coverage==4.4.2
dj-database-url==0.4.2
dj-static==0.0.6
Django==2.0.1
django-addanother==2.0.0
django-archive==0.1.5
django-braces==1.12.0
django-debug-toolbar==1.9.1
django-extensions==1.9.9
django-guardian==1.4.9
django-heroku==0.2.0
django-pure-pagination==0.3.0
django-recaptcha==1.3.1
django-toolbelt==0.0.1
django-webtest==1.9.2
docutils==0.14
funcsigs==1.0.2
gunicorn==19.7.1
idna==2.6
Upvotes: 2
Views: 2710
Reputation: 101
As you know, when you are running tests, Django isolates the changes made to the database. That is why it tries to create a database which is denied by the DB engine. You can either:
Create a database, grant access to the user and use --keepdb
to run the tests
Or grant access to the DB user to create a database. Something like:
ALTER USER username CREATEDB;
Upvotes: 0
Reputation: 2958
I solved the problem by reorganizing my settings file according to the pattern suggested here Recommended Django Project Layout.
Now my test runs fine on pythonanywhere.
Btw, I created a gist here which deals with the problems of virtual environments and layouts and how to handle virtual environment variables.
Upvotes: 1
Reputation: 1966
This is a common and correct behavior. Django when testing will always try to create new database, and you should never try to test you application on your live/production database.
Your tests should be constructed in a way, where you create your objects and then test their behavior. You are using postgres, on heroku and mysql on development server. If you want to use this databases to test you app, you have to add django user to you postgres/mysql with rights to create and delete databases/tables.
You can also avoid this by adding this setting to your settings.py (this is what I like to do when I do not use any other extensions and sqlite3 database is just enough. I run my tests by typing python manage.py test
if any([arg in sys.argv for arg in ['jenkins', 'test']]):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'mydatabase',
}
}
Upvotes: 3
Reputation: 345
I think you should change how you format your settings.py, you must not put if conditions inside it but use different settings based on the environment you are working on!
I recommend you to read this tutorial.
When you have the proper layout you can change the database in the different settings file ;)!
Upvotes: 0