DB Configuration¶
Uvicore utilizes encode/databases as an async adapter for SQLAlchemy Core (core is the query builder only, NO SQLAlchemy ORM). This was in place before SQLAlchemy 1.4 came out, which is now async. At some point Uvicore will be updated to remove the encode/databases
dependency. Keep in mind that Uvicore does NOT utilize SQLAlchemy for an ORM as Uvicore has a custom Pydantic based ORM that is more fluent and elegant.
Because Uvicore database utilizes SQLAlchemy Core, Uvicore supports any database engine that SQLAlchemy supports including MySQL, PostgreSQL, MSSQL etc...
Dependencies¶
In order to use the database layer with Uvicore you must first ensure you have installed the database
extras from the framework. This is by default already included in the uvicore-installer
.
# Poetry pyproject.toml
uvicore = {version = "0.1.*", extras = ["database", "redis", "web"]}
# Pipenv Pipfile
uvicore = {version = "==0.1.*", extras = ["database", "redis", "web"]}
# requirements.txt
uvicore[database,redis,web] == 0.1.*
After the database extras have been installed you must update your config.package.py
dependencies
OrderedDict in config/package.py
'dependencies': OrderedDict({
'uvicore.foundation': {
'provider': 'uvicore.foundation.services.Foundation',
},
# ...
'uvicore.database': {
'provider': 'uvicore.database.services.Database',
},
# ...
}),
Notice the ORM dependency does not need to be defined. Uvicore can use a raw query builder level database access layer without an ORM.
Connection Strings¶
Uvicore uses your config/database.py
[which is included from package.py
] configuration file to store connection strings. Add the proper connection, be sure to use the .env
file along with the env()
helper to keep your secrets out of git.
config = {
# ...
'database': {
'default': env('DATABASE_DEFAULT', 'wiki'),
'connections': {
# SQLite Example
# 'wiki': {
# 'driver': 'sqlite',
# 'database': ':memory',
# 'prefix': None,
# },
# MySQL Example
'wiki': {
'dialect': env('DB_WIKI_DIALECT', 'mysql'),
'sync_driver': env('DB_WIKI_SYNC_DRIVER', 'pymysql'),
'async_driver': env('DB_WIKI_ASYNC_DRIVER', 'aiomysql'),
'host': env('DB_WIKI_HOST', '127.0.0.1'),
'port': env.int('DB_WIKI_PORT', 3306),
'database': env('DB_WIKI_DB', 'wiki'),
'username': env('DB_WIKI_USER', 'username'),
'password': env('DB_WIKI_PASSWORD', 'password'),
'prefix': env('DB_WIKI_PREFIX', None),
# All options are passed directly to the specified driver.
'sync_driver_options': {
'ssl': env.bool('DB_WIKI_SSL', False),
},
'async_sync_driver_options': {
'ssl': env.bool('DB_WIKI_SSL', False),
}
},
},
},
# ...
}
options
dictionary are values passed directly to the driver
connection. The default pymysql
dialect in encode/databases
is aiomysql
which accepts an SSL parameter among others.
Note
The reason configs are referenced from config/package.py
instead of config/app.py
is because config/package.py
is meant to be overridden by any developer consuming your app as a package inside their own app. The package consumer gets to change where your package stores data. Devs can also override using their .env
file so be sure to use env('XYZ')
in your configs.
Drivers and Dialects¶
Uvicore uses encode/databases as an async layer just before SQLAlchemy Core. Therefore Uvicore is subject to all drivers and dialects supported by encode/databases
- Driver:
mysql
- Dialects:
- asdf
- Dialects:
View from CLI¶
From the Uvicore CLI, you can see all deeply merged connection strings for your app and any Uvicore package dependencies that use the DB by running
./uvicore db connections