Opened 16 years ago

Closed 16 years ago

Last modified 16 years ago

#10492 closed (wontfix)

Database connection string

Reported by: lao Owned by: nobody
Component: Database layer (models, ORM) Version:
Severity: Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I propose to use a connection string, instead of DATABASE_* settings

# settings.py
...
DATABASE = 'postgresql://djangouser:djangopassword@host/djnagodb'
DATABASE_OPTIONS = {
    ...
}

Getting connection settings from someapp, instead

# someapp.py
from django.conf import settings
dbname = settings.DATABASE_NAME
# or 
from django.db import settings
dbname = settings.DATABASE_NAME

using

# someapp.py
from django.db import db # or some other object
dbname = db.name

Example
(sory for long regex)

from re import compile

class DBConectionStr:
    """
    Formats:
        sqlite3://path/to/file
        dbtype://dbuser/dbname
        dbtype://dbuser:dbpassword/dbname
        dbtype://dbuser:dbpassword@dbhost/dbname 
        dbtype://dbuser:dbpassword@dbhost:port/dbname
        dbtype://dbuser(ROLE):dbpassword@dbhost/dbname
    Example:
       c = DBConection('sqlite3:///tmp/db.sqlite3') 
    """
    def __init__(self, cstr):
        __re_dbstr = compile(r'^(?P<engine>[^:]+)://((?P<user>[^\(:]+)(\((?P<role>.+)\))?(:(?P<password>[^@]+))?(@(?P<host>[^\/:]+)(:(?P<port>\d+))?)?)?/(?P<name>.+)')
        try:
            self.__db = __re_dbstr.search(cstr).groupdict()
            # Fix for sqlite path
            if self.__db['engine'].startswith('sqlite'):
                self.__db['name'] = "/%s" % self.__db['name']
        except:
            self.__db = {}
            #raise SomeException()

    def keys(self):
       return self.__db.keys()

    def items(self):
       return self.__db.items()

    def __getitem__(self, key):
        return self.__db.get(key, None)

    def __getattr__(self, key):
        return self.__db.get(key, None)

#c = DBConectionStr('sqlite3:///:memory:')
#c = DBConectionStr('sqlite3:///tmp/django.sqlite3')
#c = DBConectionStr('mysql://user1/django')
#c = DBConectionStr('mysql://user1:password1/django')
#c = DBConectionStr('mysql://user1:password1@host1/django') 
#c = DBConectionStr('mysql://user1:password1@host1:1234/django')
#c = DBConectionStr('postgresql://user1(role1):password1@host1/django')
c = DBConectionStr('postgresql://user1(role1):password1@host1:1234/django')
for i in c.items():
    print "%-8s: %s" % i
# or
#print c.engine, c.name 

Output

engine  : postgresql
name    : django
host    : host1
role    : role1
user    : user1
password: password1
port    : 1234

Change History (2)

comment:1 by Russell Keith-Magee, 16 years ago

Resolution: wontfix
Status: newclosed

Umm... Why? You want to replace a clear and well defined settings framework with a great big regex and wrapper class. I fail to see any advantage to the proposed approach.

comment:2 by lao, 16 years ago

I don't think what wrapper makes django many slower, but more flexible definition

Compare current

# some simple project using sqlite
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = '/tmp/db.sqlite'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

And clear style

DATABASE = 'sqlite3:///tmp/db.sqlite'

many people use more than one connection to the databases in their projects (eg for replication).
Django good framework, it supports many things that needed large projects (such as caching).
I think that at one fine day the project will include support for multiple connections. and imagine it as

...
DATABASES = (
    ('db_alias1', 'mysql://user1:password1@host1/django'),
    ('db_alias2', 'mysql://user2:password2@host2/django'),
)
...

I think it first step to support that

Note: See TracTickets for help on using tickets.
Back to Top