How to change part of file via ansible template - django

db_conn.j2:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'db_name',
'USER': 'db_user',
'PASSWORD': 'db_pass',
'HOST': 'localhost',
'PORT': '5432',
}
}
main.yml:
tasks:
- name: Set DB settings
template: src="/vagrant/ansible/templates/db_settings.j2" dest="{{ proj_dev }}/proj/settings.py"
tags:
- template
In my task file settings.py will be replaced on db_conn.j2.
But i need to change only DATABASES option in destination file (settings.py).
Can i do this via template? Or better use replace?
Is there other way in ansible for set django-settings?

The template module will override the complete file. There is no option to only replace a specific section. That's the idea of a template.
You could move the DATABASES section out to another file, and then from database.py import *, but then of course you'd have the same problem: You need to replace the DATABASES section with the import rule.
So yes, the replace module or the lineinfile module are generally better suited to replace a section of a file.
But you're lucky, Stouts has created a django role:
You can install it in your project with:
ansible-galaxy install Stouts.django

The blockinfile module introduced in Ansible 2.0 does exactly what you want. It will create and manage a block with special starting and ending marks ("BEGIN/END ANSIBLE MANAGED BLOCK" by default) in your file.

Related

Disabling a database for testing when multiple databases configured

I have two databases configured in my app:
DATABASES = {
'default': { ... }
'legacy': { ... }
}
The legacy database is only used in a particular part of the app (I've added it as a second database for convenience).
This works fine, except that when I try to run tests, Django tried to create a test database for the legacy database, causing an error:
Got an error creating the test database: (1044, "Access denied for user ... to to database 'test_...'")
How can I tell Django not to create a test database for the second legacy database?
I thought setting the following would work:
DATABASES['legacy']['TEST'] = {
'NAME': None,
'CREATE_DB': False
}
but that doesn't seem to help
Seems looks like a common issue with multiples databases and testing in Django. Here is the way I generally deal with it.
DATABASES = {
'default': { ... }
'legacy': { ... }
}
# You can add here any other type of control (not prod, debug == True, etc.)
if "test" in sys.argv:
del DATABASES["legacy"]
# Or
DATABASES = { "default": DATABASES["default"] }
This works great in the case you have only one setting file, you can easily adapt for other cases.
If you are handling many databases another option could be to start from the ground up inside your tests settings:
DATABASES = {
'default': { ... }
'legacy': { ... }
}
# You can add here any other type of control (not prod, debug == True, etc.)
if "test" in sys.argv:
DATABASES = {"default": {}}
DATABASES["default"]["ENGINE"] = "django.db.backends.sqlite3"
# Etc... Add want you need here.

WARNING: Django_mysql.w001

I am developing an E-commerce website using Python 3.6. I made a fresh installation of Django 2.0.6 and connected it to a MySQL database (on the localhost) by defining the Database variables in settings.py as below:
DATABASES = {
'default': {
'ENGINE' : 'django.db.backends.mysql',
'NAME' : 'moda',
'OPTIONS' : {
'init_command' : "SET sql_mode='STRICT_TRANS_TABLES'",
'init_command' : 'SET innodb_strict_mode=1',
'charset' : 'utf8mb4',
},
'USER' : 'root',
'PASSWORD' : '',
'SERVER' : 'localhost',
'PORT' : '3306'
}
}
and after running the python manage.py check command using cmd, I am getting the following warning:
(django_mysql.W001) MySQL Strict Mode is not set for database connection 'default'
HINT: MySQL's Strict Mode fixes many data integrity problems in MySQL, such as data truncation upon insertion, by escalating warnings into errors. It is strongly recommended you activate it. See: https://django-mysql.readthedocs.io/en/latest/checks.html#django-mysql-w001-strict-mode
I even used ' init_command': "SET sql_mode='STRICT_TRANS_TABLES'", and I'm still getting the warning!
I would be so grateful if some expert could show me the right way to fix this!
Thanks Guys.
Author of django-mysql here.
You have two 'init_command' keys in the dictionary, so only the second one will be in there after parsing - Python just silently handles duplicates like this. Hint: use flake8 to lint your source code, as it detects this and warns you.
Additionally, the two SET commands can be combined, giving:
...
'OPTIONS': {
'init_command': "SET sql_mode='STRICT_TRANS_TABLES', innodb_strict_mode=1",
'charset': 'utf8mb4',
},
...
HTH!

Elasticsearch - find exists index patterns

I'm using Python script that fetch data from Rally API, manipulate it and send to Elasticsearch.
I'm trying to figure how to find my exist index/s in script code. My ES instance is quite simple:
es = Elasticsearch([{'host': 'myIP', 'port': 9200}])
I cannot find where's exist index in this instance
My purpose is to state a condition for updating my index/s data
Any idea?
tnx
OK I found the solution and it's quite simple to use. Just type:
from elasticsearch import Elasticsearch
es = Elasticsearch([{'host': 'host_ip', 'port': 9200}])
if es.indices.exists(index = 'index_name')
#set a condition here

how to failover Redis with Django

What I want to do is to failover Redis with Django, but cannot find the way to do it.
What I've setup is as follows:
I'm using Redis as a session backend.
I've setup two Redis servers in master-slave relationship that when master fails, slave automatically becomes master (using Sentinnel)
I setup settings.py like this
CACHES = {
'default': {
'BACKEND': 'redis_cache.RedisCache',
'LOCATION':[
"127.0.0.1",
"IPofSlave"
],
'OPTIONS': {
'PASSWORD': "xxxxxxxx",
'DB': 0,
}
}
}
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = "default"
I want Django to use only the master normally, and switch automatically to slave when it can't connect to the master.
How could I do this by editing settings.py or should I take another way around?
I would probably go with something like https://github.com/KabbageInc/django-redis-sentinel/blob/master/README.md which adds sentinel support to the Django Redis plugin. There may be others more suitable, this was top of the list in a Google search for Django sentinel.

Specify Django Test Database names in settings.py

I'm specifying the databases using a python object:
DATABASES = {
'default':{
'ENGINE':'mysql',
'NAME':'testsqldb',
'USER':'<username>',
'PASSWORD':'<password>',
},
'dynamic_data':{
'ENGINE': 'sqlite3',
'NAME':'',
'USER':'',
'PASSWORD':''
},
}
How can I specify the name of my test database? I've been trying to use TEST_NAME = 'auto_tests' in the settings.py file. However, when I run python manage.py tests <app_name> I get the following message:
Creating test database 'default'...
Got an error creating the test database: (1007, "Can't create database 'test_testsqldb'; database exists")
Type 'yes' if you would like to try deleting the test database 'test_testsqldb', or 'no' to cancel:
I'm expecting the system to create a separate database when running my tests, presumably called 'auto_tests_testsqldb'; however, it's still asking me about test_testsqldb.
Any advice is appreciated!
In Django 1.6 and below, TEST_NAME should be a key of one of your database dictionaries. But in Django 1.7 and above, you use a TEST key which is a dictionary of settings for test databases.
You probably want:
DATABASES = {
'default':{
'ENGINE':'mysql',
'NAME':'testsqldb',
'USER':'<username>',
'PASSWORD':'<password>',
'TEST': {
'NAME': 'auto_tests',
}
},
'dynamic_data':{
'ENGINE': 'sqlite3',
'NAME':'',
'USER':'',
'PASSWORD':''
},
}
Alternatively, perhaps you are wanting to use a different engine for your tests? In that case, I think you'll just have to create a separate settings file for testing. It can import from your standard settings module and override DATABASES.