9

is It possible to create a single py file with my database credentials for connecting to MySQL database Ex.

con = [ [ip='0.0.0.0'],[username = 'root'],
[password='pswd'],[database='test']]

And then use this file on another file.

like

import dbcon.py*

dbcon.sort

con = mdb.connect(info from py file goes here.)
4
  • well, you can. and i see how it can be helpful. you can even make connection in one file, and import it and use in many other files. however, it's not good idea to mix data and code. we don't put HTML or JS in python code. put your configuration data in another file. Commented Mar 20, 2017 at 15:05
  • why is it not a good idea is it a safety concern or just bad practice? Commented Mar 20, 2017 at 15:17
  • both. it's goot to keep different type of code and data separate. mixing all in one place is called tight coupling and it's bad programming practice - you end up with a lot of dependencies, hard-coded configurations etc in random places and any change is huge pain. AND it's not safe, your credentials go to the code repository and are stored in every code backup etc. and it's much easier to restrict access to single config file, then to many py files with some sensitive data. Commented Mar 20, 2017 at 15:25
  • what you can do, you can still create this single connection function and import it wherever you need. but you put you credentials in separate config file. config read can be global, or you can implement it in connection function. Commented Mar 20, 2017 at 15:26

2 Answers 2

24

It is possible, but it's not good idea to mix code and data (any kind - configuration, HTML etc), for at least two reasons:

  • Design - you end up with so called high coupling. Situation where there is a lot of dependencies, hard to follow, and your app is more and more difficult to modify.
  • Security - your credentials sooner or later end up in some code backup archive or repository. Config file can be additionally encrypted, py file not really. If it's a web app, it's easier to restrict access to single config file then to all py files that can have sensitive data.

You can still create this separate, easy to use, connection handling function. But move your connection credentials to separate configuration file.

config.ini:

[mysqlDB]
host = '0.0.0.0'
db = 'test'
user = 'root'
pass = 'pswd'

You can read configuration in your connection py file or make it more global (ie singleton?). If you want to read configuration in connection file:

storage.py:

import configparser
import MySQLdb.cursors

config = configparser.ConfigParser()
config.read('config.ini')

def connect():
    return MySQLdb.connect(host = config['mysqlDB']['host'],
                           user = config['mysqlDB']['user'],
                           passwd = config['mysqlDB']['pass'],
                           db = config['mysqlDB']['db'])

Usage example:

import storage

conn = storage.connect()
Sign up to request clarification or add additional context in comments.

7 Comments

@brandon If this answers your question, please award it the green tick (and possibly an upvote for being helpful), otherwise please explain what is still not clear.
yes it was perfect I apologize for the delay I have been very ill but thank you for your reply and example. and very well wrote explanation.
and if I'm reading this correctly I can use it as. query=(myquery) conn = storage.connect() with conn: cur = conn.cursor() cur.execute(query). I apologize for the way this looks the functioning of this site still confuses me I'm trying though.
@Brandon yes, if i read your code correctly, you get it right :)
I think you have to remove the quotations around the values in the ini file. I had to remove them for it to work.
|
0
  • For this example, I was created on GitHub where you can view and run code.
  • The test presents the solution of the question itself, ie how the connection is included from the second module, as well as the parameters for the database.
└──GitHub
   ├── config.ini
   ├── db_lib.py
   ├── python_mysql_dbconfig.py
   └── test.py

A shorter version is presented below

First, create a database configuration file named config.ini and define a section with four parameters as follows:

[mysql]
HOST     = 127.0.0.1
USER     = root
PASSWORD = root
DATABASE = db

Second, create a new module named python_mysql_dbconfig.py that reads the database configuration from the config.ini file and returns a dictionary object:

pip install configparser
from configparser import ConfigParser


def read_db_config(filename='config.ini', section='mysql'):
    """ Read database configuration file and return a dictionary object
    :param filename: name of the configuration file
    :param section: section of database configuration
    :return: a dictionary of database parameters
    """
    # create parser and read ini configuration file
    parser = ConfigParser()
    parser.read(filename)

    # get section, default to mysql
    db = {}
    if parser.has_section(section):
        items = parser.items(section)
        for item in items:
            db[item[0]] = item[1]
    else:
        raise Exception('{0} not found in the {1} file'.format(section, filename))

    return db

Let’s test this module:

# db_lib.py

from python_mysql_dbconfig import read_db_config

print(read_db_config())

output:

{'host': '127.0.0.1', 'user': 'root', 'password': 'root', 'database': 'db'}

Third, in the db_lib.py module (comment on the test) that uses the MySQLConnection object to connect to the python_mysql database.

from mysql.connector import MySQLConnection, Error
from python_mysql_dbconfig import read_db_config

# print(read_db_config())


def connect():
    """ Connect to MySQL database """

    db_config = read_db_config()
    conn = None
    try:
        print("Connecting to MySQL database...")
        conn = MySQLConnection(**db_config)

        if conn.is_connected():
            print("Connection established.")

            cursor = conn.cursor()
            cursor.execute("SELECT VERSION()")

            row = cursor.fetchone()
            print("Server version:", row[0])
        else:
            print("Connection failed.")

    except Exception as error:
        print(error)

    finally:
        if conn is not None and conn.is_connected():
            conn.close()
            print("Connection closed.")


if __name__ == "__main__":
    connect()

Let’s examine the module in greater detail:

  • First, import necessary objects including MySQLConnection - pip install mysql-connector-python, Error from MySQL Connector/Python package and read_db_config from python_mysql_dbconfig module.
  • Second, read the database configuration and pass it to create a new instance of MySQLConnection object in the connect() function.

output:

>python db_lib.py
Connecting to MySQL database...
Connection established.
Server version: 8.0.22
Connection closed.

Note

  • There are other drivers for connecting to the base, such as PyMySQL
import pymysql

# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='user',
                             password='passwd',
                             database='db')

Configuration files in python:

# Write data to a file:

import json

config = {"key1": "value1", "key2": "value2"}

with open('config1.json', 'w') as f:
    json.dump(config, f)


# Read data from a file:

import json

with open('config.json', 'r') as f:
    config = json.load(f)

#edit the data
config['key3'] = 'value3'

#write it back to the file
with open('config.json', 'w') as f:
    json.dump(config, f)
import yaml

with open("example.yaml", 'r') as stream:
    try:
        print(yaml.safe_load(stream))
    except yaml.YAMLError as exc:
        print(exc)
import os

os.getenv('DATABASE_NAME')
# Standard
from envparse import env

# Schema
from envparse import Env

env = Env(BOOLEAN_VAR=bool, LIST_VAR=dict(cast=list, subcast=int))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.