1

I have a site that has about 7 dbs (country specific instances of the site) and I have a lot of repetition in the DATABASES dict in settings, as really the only thing that changes is the DATABASE key, for each entry.

So I wanted to build the dict dynamically in settings. My code works fine and builds the same dict as I had manually entered before, but for some reason I get this error when I try to run it:

_mysql_exceptions.OperationalError: (1046, 'No database selected')

Here's the code I'm using in settings to generate the dict:

DATABASES = {}

for d in DBS:
    #SITE_INSTANCE, e.g. 'dev' and DBS is a list of db names
    name = '%s_%s' % (SITE_INSTANCE, d)   

    if not DATABASES:   #first item - set up 'default'
        d = 'default'
    DATABASES[d] = {}       
    DATABASES[d]['name'] = name
    DATABASES[d]['ENGINE'] = DB_ENGINE    
    DATABASES[d]['USER'] = DB_USERNAME
    DATABASES[d]['PASSWORD'] = DB_PASSWORD

As I said the generated dict is indistinguishable from the dict I entered manually. I can't see why this wouldn't work.

2 Answers 2

3

You want 'NAME', not 'name'.

Sign up to request clarification or add additional context in comments.

1 Comment

That fixes the immediate problem, but doesn't help for variables other than the hardcoded NAME, ENGINE, USER and PASSWORD.
1

The below code provides a few different ways of specifying database settings, including allowing old, Django 1.2-style DATABASE_FOO declarations:

# Settings with no underscores in their names apply to the "default"
# database out-of-the-box
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'foo.sqlite'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''

# Since this setting has underscores in it, it needs to be specified the
# long way to disambiguate
DATABASE_default_SUPPORTS_TRANSACTIONS = True

# Specifying any settings for a database will implicitly copy everything
# else from default.
DATABASE_baz_NAME = 'baz.sqlite'

# Databases can also be defined with Django 1.2-style dicts
DATABASE_bar = {
    'NAME': 'bar.sqlite',
}

# Empty dicts will create complete clones of default
DATABASE_clone = {}

...and here's the implementation:

databases = {}
database_global_settings = set([
    'DATABASE_ROUTERS',
])
current_settings = globals()
for (k, v) in current_settings.items():
    if k in database_global_settings:
        continue
    if k.startswith('DATABASE_'):
        if k.count('_') >= 2:
            (dummy_label, dbname, variable) = k.split('_', 2)
            if not dbname in databases:
                databases[dbname] = {}
            databases[dbname][variable] = v
        elif isinstance(v, dict):
            (dummy_label, dbname) = k.split('_', 1)
            if dbname in databases:
                databases[dbname].update(v)
            else:
                databases[dbname] = v
        else:
            # legacy configuration for default database
            dbname = 'default'
            (dummy_label, variable) = k.split('_', 1)
            if not dbname in databases:
                databases[dbname] = {}
            databases[dbname][variable] = v
        del globals()[k]
for database_name in databases:
    if database_name != 'default':
        for (k, v) in databases['default'].iteritems():
            databases[database_name].setdefault(k, v)
DATABASES = databases

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.