Repository: joke2k/django-environ

Issue:
Database url.scheme only works for built-in schemes (backends)
I haven't find any issue related to this topic, so sorry in advance if it is something that has been already discussed.

According to this code inside ```Env.db_url_config()```:
``` python
class Env(object):
    # [...]
   @classmethod
    def db_url_config(cls, url, engine=None):
        # [...]
        if engine:
            config['ENGINE'] = engine
        if url.scheme in Env.DB_SCHEMES:
            config['ENGINE'] = Env.DB_SCHEMES[url.scheme]


        if not config.get('ENGINE', False):
            warnings.warn("Engine not recognized from url: {0}".format(config))
            return {}
```

Actually, the only way to set up a custom backend for a database is using the ```engine``` parameter when we call ```Env.db()``` at the same time that we put an invalid ```url.scheme``` in ```DATABASE_URL``` (what is weird) or we put our custom one again (that it is going to be considered invalid anyway because it doesn't exist in ```Env.DB_SCHEMES```), what is redundant.

``` python
import environ
env = environ.Env()
env.db('DATABASE_URL', engine='path.to.my.custom.backend')
# Having DATABASE_URL=path.to.my.custom.backend://user:password@host:post/database
```

This code fix this situation, simply letting pass the custom scheme as a valid one if it doesn't match one of the built-in ```DB_SCHEMES```.

``` python
if url.scheme in Env.DB_SCHEMES:
    config['ENGINE'] = Env.DB_SCHEMES[url.scheme]
else:
    config['ENGINE'] = url.scheme
```


Discussion:
coveralls: 
[![Coverage Status](https://coveralls.io/builds/15544546/badge)](https://coveralls.io/builds/15544546)

Coverage decreased (-0.2%) to 88.205% when pulling **493f52368367356e86b2a3e72c79215a2d2324ef on ddiazpinto:fix-custom-db-backend-url-scheme** into **628ed38e540ec9a6f3aff622953948e54f14a76d on joke2k:develop**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/15544546/badge)](https://coveralls.io/builds/15544546)

Coverage decreased (-0.2%) to 88.205% when pulling **493f52368367356e86b2a3e72c79215a2d2324ef on ddiazpinto:fix-custom-db-backend-url-scheme** into **628ed38e540ec9a6f3aff622953948e54f14a76d on joke2k:develop**.

ddiazpinto: @joke2k Is there something we can do to help you handling these issues?
ddiazpinto: I have added a simple patch to fix #175 too, because it is closely related to this PR.

After merging this PR, it is going to be possible to define a custom engine using ```engine``` attribute of ```Env.db()``` or the url.schema present in ```DATABASE_URL```. In case both were present, the ```engine``` would be used.

Patch:
diff --git a/environ/environ.py b/environ/environ.py
index 9a9f906..a1febab 100644
--- a/environ/environ.py
+++ b/environ/environ.py
@@ -422,8 +422,11 @@ class Env(object):
 
         if engine:
             config['ENGINE'] = engine
-        if url.scheme in Env.DB_SCHEMES:
-            config['ENGINE'] = Env.DB_SCHEMES[url.scheme]
+        else:
+            config['ENGINE'] = url.scheme
+
+        if config['ENGINE'] in Env.DB_SCHEMES:
+            config['ENGINE'] = Env.DB_SCHEMES[config['ENGINE']]
 
         if not config.get('ENGINE', False):
             warnings.warn("Engine not recognized from url: {0}".format(config))


Test patch:
diff --git a/environ/test.py b/environ/test.py
index 2a9e192..92f5c0f 100644
--- a/environ/test.py
+++ b/environ/test.py
@@ -18,6 +18,7 @@ class BaseTests(unittest.TestCase):
     SQLITE = 'sqlite:////full/path/to/your/database/file.sqlite'
     ORACLE_TNS = 'oracle://user:password@sid/'
     ORACLE = 'oracle://user:password@host:1521/sid'
+    CUSTOM_BACKEND = 'custom.backend://user:password@example.com:5430/database'
     REDSHIFT = 'redshift://user:password@examplecluster.abc123xyz789.us-west-2.redshift.amazonaws.com:5439/dev'
     MEMCACHE = 'memcache://127.0.0.1:11211'
     REDIS = 'rediscache://127.0.0.1:6379/1?client_class=django_redis.client.DefaultClient&password=secret'
@@ -52,6 +53,7 @@ class BaseTests(unittest.TestCase):
                     DATABASE_ORACLE_URL=cls.ORACLE,
                     DATABASE_ORACLE_TNS_URL=cls.ORACLE_TNS,
                     DATABASE_REDSHIFT_URL=cls.REDSHIFT,
+                    DATABASE_CUSTOM_BACKEND_URL=cls.CUSTOM_BACKEND,
                     CACHE_URL=cls.MEMCACHE,
                     CACHE_REDIS=cls.REDIS,
                     EMAIL_URL=cls.EMAIL,
@@ -220,6 +222,14 @@ class EnvTests(BaseTests):
         self.assertEqual(sqlite_config['ENGINE'], 'django.db.backends.sqlite3')
         self.assertEqual(sqlite_config['NAME'], '/full/path/to/your/database/file.sqlite')
 
+        custom_backend_config = self.env.db('DATABASE_CUSTOM_BACKEND_URL')
+        self.assertEqual(custom_backend_config['ENGINE'], 'custom.backend')
+        self.assertEqual(custom_backend_config['NAME'], 'database')
+        self.assertEqual(custom_backend_config['HOST'], 'example.com')
+        self.assertEqual(custom_backend_config['USER'], 'user')
+        self.assertEqual(custom_backend_config['PASSWORD'], 'password')
+        self.assertEqual(custom_backend_config['PORT'], 5430)
+
     def test_cache_url_value(self):
 
         cache_config = self.env.cache_url()
diff --git a/environ/test_env.txt b/environ/test_env.txt
index c0112c3..a891138 100644
--- a/environ/test_env.txt
+++ b/environ/test_env.txt
@@ -28,4 +28,5 @@ INT_TUPLE=(42,33)
 DATABASE_ORACLE_TNS_URL=oracle://user:password@sid
 DATABASE_ORACLE_URL=oracle://user:password@host:1521/sid
 DATABASE_REDSHIFT_URL=redshift://user:password@examplecluster.abc123xyz789.us-west-2.redshift.amazonaws.com:5439/dev
-export EXPORTED_VAR="exported var"
\ No newline at end of file
+DATABASE_CUSTOM_BACKEND_URL=custom.backend://user:password@example.com:5430/database
+export EXPORTED_VAR="exported var"