Reputation: 2082
In my current project, I have two servers: production
and staging
.
The staging
server uses the default MySQL Django connector.
The production
server uses a custom connector for MariaDB.
The information from the database is retrieved through raw queries. I can't use ORM for this project.
Both staging
and production
are connected to the project's git repository.
If I push a commit with the specific settings for the staging server, when I git pull from production server it won't work and vice versa.
I need to create a mechanism that detects if the server is production or staging and based on that it executes the specific code for MariaDB or MySQL.
The conflicting files are: settings.py
(no explanations needed) and db.py
(contains all the logic of the database, here are implemented the functions that are responsible for making queries to the database).
STAGING SERVER
db.py
(truncated):
#!/usr/bin/python
from django.db import connection
import re
from collections import namedtuple
def get_genome_id_from_start_value(start):
results = []
cursor = connection.cursor()
cursor.execute("SELECT record_id FROM `db-dummy`.g_info WHERE start = %s", ('{}%'.format(start),))
columns = [column[0] for column in cursor.description]
results = []
for row in cursor.fetchall():
results.append(dict(zip(columns, row)))
return results[0]['record_id']
settings.py
(truncated):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db-dummy',
'USER': 'user',
'PASSWORD': 'password',
'HOST': '127.0.0.1',
'PORT': '',
'TIME_ZONE': 'UTC',
}
}
PROD SERVER
db.py
(truncated)
#!/usr/bin/python
import mariadb
import re
from collections import namedtuple
def get_genome_id_from_start_value(start):
conn = mariadb.connect(
user="user",
password="password",
host="localhost",
database="db-dummy")
results = []
cursor = conn.cursor(named_tuple=True)
try:
cursor.execute("SELECT record_id FROM `db-dummy`.g_info WHERE start = ?", (start,))
columns = [column[0] for column in cursor.description]
results = []
for row in cursor.fetchall():
results.append(dict(zip(columns, row)))
return results[0]['record_id']
except mariadb.Error as e:
print(f"Error: {e}")
settings.py
(truncated):
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
What I have tried:
settings.py
:
STAGING = 'staging'
PROD = 'prod'
if socket.gethostname().startswith('ip-177-77-7-777'):
DJANGO_HOST = STAGING
else:
DJANGO_HOST = PROD
if PROD == DJANGO_HOST:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'db-dummy',
'USER': 'user',
'PASSWORD': 'password',
'HOST': '127.0.0.1',
'PORT': '',
'TIME_ZONE': 'UTC',
}
}
I think that will work for settings.py
but now I need a solution for db.py
.
Any suggestions?
Upvotes: 0
Views: 362
Reputation: 3725
Quick Solution, Create a common function which returns cursor, for production it will return a cursor for production and for statging it return a cusror for staging and use this cursor in get_genome_id_from_start_value.
from django.conf import settings
def get_cursor():
if settings.PROD == settings.DJANGO_HOST:
conn = mariadb.connect(
user="user",
password="password",
host="localhost",
database="db-dummy")
return conn.cursor(named_tuple=True)
else:
return cursor = connection.cursor()
def get_genome_id_from_start_value():
cursor = get_cursor()
----
One better way to use django_environ, then you can define the evironment sepecfic constants, databases to a file and can these values in python files https://pypi.org/project/django-environ/
.env
DJANGO_HOST=PROD
DEBUG=false
----
.env
DJANGO_HOST=STAGING
DEBUG=on
-----
settings.py
environ.Env.read_env()
env = environ.Env(DEBUG=(bool, False))
DEBUG = env('DEBUG')
DJANGO_HOST = env('DJANGO_HOST')
Upvotes: 1