Django(djongo) can't connect to MondoDB Atlas after Heroku deployment - python

I managed to get it working locally (different cluster, separate settings.py), but not after when deployed to Heroku.
Heroku - automatically adds DATABASE_URL config var with a postgresql, and I cannot remove/edit it.
MongoDB Atlas - I've set the MongoDB Atlas cluster to allow IPs from everywhere. And the password has no funny characters.
django production settings.py
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'DBProd',
'CLIENT': {
'host': "mongodb+srv://XXX:YYY#ZZZ.pc4rx.mongodb.net/DBProd?retryWrites=true&w=majority",
}
}
}
I ran migrate straight after the deployment and it's all green OKs
heroku run python manage.py migrate
Everything works functional wise, just that the data are not stored in the MongoDB Atlas cluster. There are lots of posts from various sites on this, but they all have different instructions... Some of the posts I tried to follow:
https://developer.mongodb.com/how-to/use-atlas-on-heroku/
Django + Heroku + MongoDB Atlas (Djongo) = DatabaseError with No Exception
Connecting Heroku App to Atlas MongoDB Cloud service
-- A very confused beginner

For whoever lands on this. Add 'authMechanism': 'SCRAM-SHA-1', below 'host' will fix the issue.

This happened to me as well, in my case, somehow Heroku added postgresql as an add-on for my app so have to delete that first.
Check Heroku documentation about postgresql and how to destroy add-on:
https://devcenter.heroku.com/changelog-items/438
https://devcenter.heroku.com/articles/managing-add-ons
Then you need to configure MongoDB as your database by adding a MONGODB_URI config var with your database url. You should be ready to connect to your MongoDB now!
The following doc also helps:
https://www.mongodb.com/developer/how-to/use-atlas-on-heroku/

I've been having the same issue. Everything works fine locally. The problem is when deploying on Heroku. I have added 'authMechanism': 'SCRAM-SHA-1' and I have also configured MongoDB as my database by adding a MONGODB_URI config var. Heroku still autoconfigures DATABASE_URL config var with a postgresql, and I cannot remove/edit it.
In my Javascript code I used fetch('127.0.0.1:8000/<something>') which I specified in my urls.py and that way views.py read data from pymongo and returned it as a response.
After deploying my app to Heroku (and hardcoding the 127.0.0.1:8000 to <myappname>.heroku.com) the same fetch method seems to return [] instead of json containing values from MongoDB.
This is the most identical issue I found in a post I hope I'm not out of subject.

Related

With existing "mySQL Database" and "website", want to connect/synchronize both part how to accomplish by Python

Main problem: I have existing mySQL Database and website, how do I connect/synchronize both, that input or update from mySQL, can also result in website too
I did learn HTML, CSS but was required to find the way, instead input from <p> </p>, need to find a way CRUD from mySQL, and result to website
after a day of research, python django seems has the possiblity solve my problem, but all the tutorial is buttom up create an new website and new mySQL, I'm stock on connecting existing one (that the "mySQL Database" and "website"), that how far I reach , therefore want to ask the export in here, thanks
environment: I'm using python, window and mySQL
the already set website screenshot
the existing mySQL Database screenshot (MySQL Database, and using HeidiSQL )
the specific example:
if I update/change the context Nordic as Nike from mySQL, by success connect both, the website part the Nike can replace Nordic as new topic
update -
now I'm sure the "django" and "MySQL" is connected
that I craete the 'TestModel' and 'TestModel_002' from django, will also added in MySQL
conclude:
"django" and "MySQL" is connected
still not reach my original issue , insert/update data in "MySQL" can affect website
https://imgur.com/a/f1CNGQ4
now the "django" and "MySQL" is connected, but I'm looking for insert/update data in "MySQL" can affect website, seems im close, but what shall I do though?
If you want to connect your django app to an existed DB, you should just edit your django settings.py and write this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'DB_NAME',
'USER': 'DB_USER',
'PASSWORD': 'DB_PASSWORD',
'HOST': 'localhost', # Or an IP Address that your DB is hosted on
'PORT': '3306',
}
}

Celery in dokku doesn't see sqlite records

My stack is: Django, Celery(Redis broker), Dokku.
My code put the record in sqlite database and put the task for Celery:
package = Package.objects.get(pk=package_id)
package.download_status = 'QUEUE' # package is Django ORM object
package.save()
task_download_package.delay(package.id) # put a task to redis for celery
Now I need to get this object from sqlite database inside the Celery task. But inside the Celery task process I can't see the record:
#app.task(bind=True)
def task_download_package(self,
package_id: int):
try:
package = Package.objects.get(pk=package_id)
except ObjectDoesNotExist:
print("Package with pk={} not found".format(package_id)) # I HAVE GOT THIS MESSAGE
return
But when I ask package.download_status from Django process by my special endpoint I got "QUEUE" status.
It looks like Django and Celery processes has different containers or diffenrent databases.
I have checked connection.settings_dict['NAME'] and it's return the same "/app/db.sqlite3" value for Django and Celery processes.
This code without Dokku works fine, but now I need it with Dokku.
Why Celery doesn't see record in sqlite db?
Is it actually the same database? May be I need something like a Commit? (I use Django save method)
How I can fix it?
I have solved the problem by share db.sqlite3 file on common directory on Dokku host computer. And set the path in the application settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': '/home/my_user/my_company/my_app/database/db.sqlite3',
}
}
And share this directory for application container:
dokku storage:mount my_app /home/my_user/my_company/my_app/database/:/home/my_user/my_company/my_app/database/

Trouble accessing Heroku's config vars with os.environ in Django/Python

I'm hosting a Django app on Heroku and I do not want my database credentials in the settings.py file to be visible in GitHub. Rather, I want them to be accessed in Heroku's config vars. Heroku's docs says it's possible to access the config vars in Python code like this:
from boto.s3.connection import S3Connection
s3 = S3Connection(os.environ['S3_KEY'], os.environ['S3_SECRET'])
So I set the relevant config vars like this:
heroku config:set PASSWORD=madeuppassword
And I tried to access the config vars in the source code like is says like this:
DATABASES = {
'default': {
'ENGINE': os.environ['ENGINE'],
'NAME': os.environ['NAME'],
'USER': os.environ['USER'],
'PORT': os.environ['PORT'],
'PASSWORD': os.environ['PASSWORD'],
'HOST': os.environ['HOST']
}
}
However when running the server I get this error in my command prompt:
raise KeyError(key) from None
KeyError: 'ENGINE'
To the best of my knowledge I set and accessed Heroku's config vars as it's demonstrated in their docs but I keep getting this error. What am I possibly doing wrong that it keeps bringing up this error?
Any help is appreciated!

How to get node web client to talk to REST API on Heroku?

I have a node web client called bidsell, and a small Python Tornado REST API called quote. Bidsell when triggered makes regular http get calls to quote. Quote duely returns random price information as json. Works locally - want to share it online, but how? Heroku looks promising. Have tried already to deploy both bidsell and quote in the same project on heroku, each running within their own heroku web dyno or deployment container. From the logs "heroku log" both are installed correctly but only one appears to be running. So I can access the front page url of bidsell, for example, but when bidsell is triggered to go fetch quote info the quote service is not found :-( Should I be using another deployment pattern?
ok so as jr0cket suggested I created 2 heroku projects - one for the bidsell node project and one for the quote service.
In addition to the bidsell node project source files I had a procfile containing the following:
web: npm start
and a scripts section in package.json informing heroku how to start the app:
"scripts": {
"start": "gulp serve"
}
In addition to the quoteService source python file I had a procfile containing the following:
web: python quoteService.py
and a requirements.txt file containing:
tornado==3.1.1
pyrestful==0.4.1
Had the following proxy.js as middleware in the bidsell app:
'use strict';
var proxyMiddleware = require('http-proxy-middleware');
var options = {
target: 'http://quoteservce.herokuapp.com:80',
changeOrigin: true
};
var proxy = proxyMiddleware('/quote', options);
module.exports = function(){
return [proxy];
}
being called from server.js:
'use strict';
..
var middleware = require('./proxy');
module.exports = function(options) {
function browserSyncInit(baseDir, browser) {
browser = browser === undefined ? 'default' : browser;
..
var server = {
baseDir: baseDir,
routes: routes
};
server.middleware = middleware();
browserSync.instance = browserSync.init({
port: (process.env.PORT || 5000),
startPath: '/',
server: server,
browser: browser
});
}
..
gulp.task('serve', ['watch'], function () {
browserSyncInit([options.tmp + '/serve', options.src]);
});
..
};
to allow communication between bidsell and quoteService. For further background info take a look here
The running app you can find here.
May take a little while for the idle free-tier heroku dynos to fire up ;-)
Bidsell project on git.
QuoteService project on git.
As your project is two seperate technology stacks, the easiest approach is to deploy these as two separate Heroku apps. This gives you simple way to create the specific environment (languages, runtimes, libraries) needed for each app / service.
You could create an Heroku configuration variable QUOTE_REST_API for the node web client that points to the external web address. For example, using the heroku toolbelt
heroku config:set QUOTE_REST_API=https://quote-api.herokuapp.com/
Using the QUOTE_REST_API configuration variable in your node client would give a simple way to change the address of the quote without having to change your code.
If you are running two separate projects in one Heroku app, you need to ensure that you have two web: entries for the Procfile to start your separate processes. Only processes marked as web will listen to web traffic.
You may not be able to run two different web processes if you use the free tier of heroku.

Local server address for multiple users on different computers? (Python)

I'm working with some friends to build a PostgreSQL/SQLAlchemy Python app and have the following line:
engine = create_engine('postgresql+pg8000://oldmba#localhost/helloworld')
Newbie question: Instead of having to edit in "oldmba" (my username) all the time whenever I git pull someone else's code, what's the simple way to make that line equally applicable to all users so we don't have to constantly edit it? Thanks in advance!
have a config file with your settings.
It can store data in python config dictionary or variables
The config file can import from a local_settings.py file. This file can be ignored in your gitignore. It can contain your individdual settings , username , password, database urls, pretty much anything that you need to configure and that may differ depending on your enviornment (production vs devel)
This is how settings in django projects are usually handled. It allows for multiple users to devlop on the same project with different settings. You might want a 'database_url' field or something too so on production if you need to set your database to a different server but on development you use 'localhost'
# config.py
database = {
'username': 'production_username',
'password': 'production_password'
}
try:
from local_config import *
catch ImportError:
pass
# local_config.py
database = {
'username': 'your_username',
'password': 'your_password'
}
from config import *
engine = create_engine('postgresql+pg8000://{0}#localhost/helloworld'.format(database['username']))

Categories

Resources