Getting error with postgis Geodjango on Heroku - django

Postgis extension is installed:
:DATABASE=> SELECT postgis_version();
postgis_version
2.2 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
I have the following buildpacks:
https://github.com/cyberdelia/heroku-geo-buildpack.git
https://github.com/heroku/heroku-buildpack-python.git
When I run manage.py migrate I get:
AttributeError: 'DatabaseOperations' object has no attribute 'geo_db_type'
I am using the hobby deb postgres which now supports postgis
https://devcenter.heroku.com/changelog-items/792
Do I need to install a different build pack or add some additional configuration? Everything works locally using postgis.

I finally had some time to go back and look at this. It turns out the issue was Heroku was not importing my settings correctly. I was using cookiecutter-django settings scheme that imports common settings into production and for some reason Heroku was not working as expected.
My common settings contained:
DATABASES['default']['ATOMIC_REQUESTS'] = True
DATABASES['default']['ENGINE'] = "django.contrib.gis.db.backends.postgis"
And my production contained:
DATABASES['default'] = env.db("DATABASE_URL")
Heroku did not import those common settings. When I checked in the django shell in heroku the production settings had
'ENGINE': 'django.db.backends.postgresql_psycopg2', 'ATOMIC_REQUESTS': False
After adding DATABASES['default']['ENGINE'] = "django.contrib.gis.db.backends.postgis" to production settings everything is working.
Does anybody know what could be going wrong with importing settings correctly from common.py? It seems to import the rest of the settings correctly, just not the database ones.

Related

Django Unit Tests Failing on Travis CI Builds

I have a very basic Django app (Python 3.6.4) and I've written a unit test which passes locally. An in memory SQLite DB is created (by default) for the tests. When my Travis CI build runs the same tests the tests pass but the test command fails with the following error:
File "/home/travis/virtualenv/python3.6.5/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 301, in execute
return Database.Cursor.execute(self, query)
django.db.utils.OperationalError: near "SCHEMA": syntax error
The command "python manage.py test --settings=myapp.dev_settings" exited with 1.
One strange thing I notice is that when the tests are run on Travis, it's says it's reusing an existing DB and never destroys it after the tests are run:
$ python manage.py test --settings=myapp.dev_settings
Using existing test database for alias 'default'...
I don't really get that, because it should be an in memory DB and when I run it locally, a new database is created each time:
Creating test database for alias 'default'...
. . .
Destroying test database for alias 'default'...
My dev_settings.py file has a sqlite db on the filesystem, but that is only used for running the local development server:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
Travis installs all the dependencies and they match my local environment (I'm fairly sure).
Any help would be great, I'm definitely missing something obvious here!!!
This is because the Django-Heroku package sets its own Test Runner that does extra stuff with the database if it detects a CI environment, presumably to cater to their Heroku CI offering:
# Enable test runner if found in CI environment.
if 'CI' in os.environ:
config['TEST_RUNNER'] = 'django_heroku.HerokuDiscoverRunner'
The test runner does the following which does not work for SQLite:
with connection.cursor() as cursor:
cursor.execute(
"""
DROP SCHEMA public CASCADE;
CREATE SCHEMA public;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO public;
COMMENT ON SCHEMA public IS 'standard public schema';
"""
)
Unfortunately this check also detects non-Heroku CI environments such as Travis or GitLab CI and attempts to use the above configuration.
You can solve this problem by disabling the Heroku test runner like so in your settings.py:
# Configure Django App for Heroku.
django_heroku.settings(locals(), test_runner=False)
#LaSmell is correct (I had the same problem). It's because you're trying to access Heroku dependencies in your build.
BUT I can still show you how to implement a solution.
You need to do 3 things to solve this problem.
1 - Specify a new requirements doc without django-heroku
I personally made another file called requirements-build.txt and it has all the same dependencies except django-heroku==0.3.1
I just delete it out.
2 - Specify the new requirements file in .travis.yml
In your .travis.yml file just replace
install:
- pip install -r requirements.txt
with
install:
- pip install -r requirements-build.txt
3 - Account for these changes in your settings.py file
To make sure you don't import heroku-django if it's not installed, check if it can be imported first. I did:
# Try to import django-heroku depending on Travis or Heroku
try:
# Configure Django App for Heroku.
import django_heroku
django_heroku.settings(locals())
except ImportError:
found = False
This way it will only use django-heroku if it has been installed. Since Heroku uses requirements.txt by default this patch works perfectly fine.
Hope this helps! It took me a while to get it myself.
In the stack trace of the travis build I noticed an unexpected package being executed:
File "/home/travis/virtualenv/python3.6.5/lib/python3.6/site-packages/django_heroku/core.py", line 41, in teardown_databases
self._wipe_tables(connection)
The problem was I was executing my tests with a settings.py file that included Heroku (deployment) specific code:
import django_heroku
import dj_database_url
# Parse database configuration from Heroku's $DATABASE_URL (Postgres)
DATABASES = {
'default': dj_database_url.config(conn_max_age=500, ssl_require=True)
}
# Activate Django-Heroku (DATABASE_URL and all that).
django_heroku.settings(locals())
And dependencies in my requirements.txt file:
django-heroku==0.3.1
Once I remove all the Heroku config from the Travis build config, the build passes!
Still unsure how I didn't see this fail locally.

Heroku csv file not getting recognised in settings.py

i am trying to deploy my site using heroku. Being a starter just following the steps given on a website. In settings my csv and database default is not getting recognised.
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=Csv())
DATABASES = {
'default': dj_database_url.config(
default=config('DATABASE_URL')
)
}
This has nothing to do with Heroku; this wouldn't work locally either. The error message tells you all you need to know: you have not defined Csv. It's not clear what it is supposed to be, but you either need to import that function, or define it yourself.
Install python-decouple pip install python-decouple
ran into the same ordeal.

dj_database_url not properly finding heroku postgres db configurations

I am having a problem getting django to recognize my heroku postgres db. Usually the following configuration work fine, but for some reason it has stopped working on my most recent application.
In settings.py, I added the following code.
import dj_database_url
DATABASES['default'] = dj_database_url.config()
print DATABASES['default']
it prints out {'default':{}}
the heroku pg:info command returns what looks to be normal:
=== HEROKU_POSTGRESQL_WHITE_URL
Plan: Dev
Status: available
Connections: 1
PG Version: 9.2.4
Created: 2013-08-06 15:40 UTC
Data Size: 6.3 MB
Tables: 0
Rows: 0/10000 (In compliance)
Fork/Follow: Unsupported
When I go to use the database it returns
settings.DATABASES is improperly configured.
Any thoughts on why dj_database_url.config() is not properly parsing the database configurations?
Thank you for the thoughts.
EDIT:
Still don't know the reason for the above behavior, but I found a work around. I had to add the postgres db to the app before the initial push. For some reason it wasn't finding it if it was added after the first push.
This should be your db settings
DATABASES['default'] = dj_database_url.config(default='postgres://user:passwprd#host/db')
DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2'

Django App breaks Using Heroku Database Settings

When I run my Django app locally everything works just fine but when I deploy to Heroku using
import dj_database_url
DATABASES = {'default': dj_database_url.config(default='postgres://')}
For my database settings I get the following error
TypeError at /
cannot concatenate 'str' and 'NoneType' objects
you can see the full error message here http://tulsa-staging.heroku.com
Ive removed all none essential settings and isolated the problem to this setting.
So what the heck am I doing wrong here?
Why aren't you listing a host in the config string?
DATABASES = {'default': dj_database_url.config(default='postgres://localhost')}

how to use manage.py syncdb outside of Django project, such as in Tornado?

I was looking through http://lincolnloop.com/blog/2009/sep/15/using-django-inside-tornado-web-server/ and I thought it was interesting and useful to use parts of Django if we need it in Tornado.
Based on the setup in http://lincolnloop.com/blog/2009/sep/15/using-django-inside-tornado-web-server/ how can we use manage.py syncdb ?
Here's what i have tried so far:
I've tried shifting manage.py to the same folder as the tornado project, and ran manage.py syncdb but it returns saying that settings.py is not found.
than i tried to move setting.py to the same folder and ran manage.py again. It tells me that no fixtures found. This time round, I have no idea how to configure settings.py since this is not a Django project.
Any advice or thoughts?
=================updates======================
Hi all,
continuing from the above an using advice provided by Agos,
i've tried running python manage.py syncdb --settings=dj_tornado and it returns
`"Error: Can't find the file 'settings.py'` in the directory containing 'manage.py'`. It appears you've customized things.
You'll have to run django-admin.py, passing it your settings module.
(If the file settings.py does indeed exist, it's causing an ImportError somehow.)"
So what i did is to run django-admin.py syncdb --settings=dj_tornado and it returns "django.core.exceptions.ImproperlyConfigured: You haven't set the database ENGINE setting yet."
But the weird thing is that the database engine has been set. How would I go about fixing this? i'm using django 1.2.3 and Tornado 0.2 by the way.
=================updates again======================
Hi all,
i've applied the advice provided by Agos, with a settings.py file in teh same folder as manage.py, and ran the command django-admin.py syncdb --settings=dj_tornado.
I still received the error:
django.core.exceptions.ImproperlyConfigured: You haven't set the database ENGINE setting yet.
But i have already configured the database based engine as follows:
in dj_tornado.py:
from django.conf import settings
settings.configure(
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'dev.db',
}
}
)
I'm kind of at my wits end. How do i use syncdb outside of Django project?
Best.
If I got it correctly, you can just use the --settings switch to point manage.py to the dj_tornado.py, which is your settings file after all
Update 1
from the help, available at python manage.py help:
Options:
--settings=SETTINGS The Python path to a settings module, e.g.
"myproject.settings.main". If this isn't provided, the
DJANGO_SETTINGS_MODULE environment variable will be
used.
So I would try this:
python manage.py syncdb --settings=dj_tornado
Update 2
Another error, another update to the answer!
First of all, consider that that blog post is quite old (september 2009). Django's DATABASES setting has been updated since 1.2.
The syntax in the blog post was:
settings.configure(DATABASE_ENGINE='sqlite3', DATABASE_NAME='dev.db')
With Django 1.2.X this is surely not correct. This would be the equivalent version:
settings.configure(DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'dev.db'
}
})
(sorry for the horrible formatting of the code).
If this still won't work, I'd consider creating a “standard” Django settings file to import. But my bet is on the db settings syntax.
Last update, I swear
Have you tried using django-admin.py again with the new syntax? If so, and still didn't work, a minimal settings.py would be just this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'dev.db'
}
}
You can also keep the original configuration inside dj_tornado.py and use settings.py just to do syncdb.