added check for sqlite db

This commit is contained in:
Simone Robutti 2022-09-25 23:39:24 +02:00
parent dfe15a71e4
commit a80eca8a01
8 changed files with 96 additions and 44 deletions

View File

@ -20,7 +20,7 @@ base_validators = [
# url of the main Mobilizon instance to download events from # url of the main Mobilizon instance to download events from
Validator("source.mobilizon.url", must_exist=True, is_type_of=str), Validator("source.mobilizon.url", must_exist=True, is_type_of=str),
Validator("source.mobilizon.group", must_exist=True, is_type_of=str), Validator("source.mobilizon.group", must_exist=True, is_type_of=str),
Validator("db_path", must_exist=True, is_type_of=str), Validator("db_url", must_exist=True, is_type_of=str),
Validator("locale", must_exist=True, is_type_of=str, default="en-us"), Validator("locale", must_exist=True, is_type_of=str, default="en-us"),
] ]

View File

@ -1,7 +1,6 @@
[default] [default]
local_state_dir = "/var/mobilizon_reshare" local_state_dir = "/var/mobilizon_reshare"
db_name = "events.db" db_url = "sqlite:///var/mobilizon_reshare/events.db"
db_path = "@format {this.local_state_dir}/{this.db_name}"
locale= "en-us" locale= "en-us"
[default.source.mobilizon] [default.source.mobilizon]

View File

@ -3,9 +3,9 @@ from logging.config import dictConfig
from pathlib import Path from pathlib import Path
import pkg_resources import pkg_resources
import urllib3.util
from aerich import Command from aerich import Command
from tortoise import Tortoise from tortoise import Tortoise
from tortoise.contrib.fastapi import register_tortoise
from mobilizon_reshare.config.config import get_settings from mobilizon_reshare.config.config import get_settings
from mobilizon_reshare.config.publishers import publisher_names from mobilizon_reshare.config.publishers import publisher_names
@ -14,21 +14,13 @@ from mobilizon_reshare.storage.query.write import update_publishers
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def get_db_url(): def get_db_url() -> urllib3.util.Url:
"""gets db url from settings return urllib3.util.parse_url(get_settings().db_url)
Returns:
str : db url
"""
settings = get_settings()
db_path = Path(settings.db_path)
db_url = f"sqlite:///{db_path}"
return db_url
def get_tortoise_orm(): def get_tortoise_orm():
return { return {
"connections": {"default": get_db_url()}, "connections": {"default": get_db_url().url},
"apps": { "apps": {
"models": { "models": {
"models": [ "models": [
@ -50,19 +42,12 @@ TORTOISE_ORM = get_tortoise_orm()
class MoReDB: class MoReDB:
def __init__(self, path: Path):
self.path = path
# TODO: Check if DB is openable/"queriable"
self.is_init = self.path.exists() and (not self.path.is_dir())
if not self.is_init:
self.path.parent.mkdir(parents=True, exist_ok=True)
async def _implement_db_changes(self): async def _implement_db_changes(self):
migration_queries_location = pkg_resources.resource_filename( migration_queries_location = pkg_resources.resource_filename(
"mobilizon_reshare", "migrations" "mobilizon_reshare", "migrations"
) )
command = Command( command = Command(
tortoise_config=TORTOISE_ORM, tortoise_config=get_tortoise_orm(),
app="models", app="models",
location=migration_queries_location, location=migration_queries_location,
) )
@ -73,23 +58,18 @@ class MoReDB:
async def setup(self): async def setup(self):
await self._implement_db_changes() await self._implement_db_changes()
await Tortoise.init(config=TORTOISE_ORM,) await Tortoise.init(config=get_tortoise_orm(),)
if not self.is_init: await Tortoise.generate_schemas()
await Tortoise.generate_schemas()
self.is_init = True
logger.info(f"Successfully initialized database at {self.path}")
await update_publishers(publisher_names) await update_publishers(publisher_names)
@staticmethod
def register_app(app): class MoReSQLiteDB(MoReDB):
orm_data = get_tortoise_orm() def __init__(self):
register_tortoise( self.path = Path(get_db_url().path)
app, # TODO: Check if DB is openable/"queriable"
db_url=orm_data["connections"]["default"], self.is_init = self.path.exists() and (not self.path.is_dir())
modules=orm_data["apps"], if not self.is_init:
generate_schemas=True, self.path.parent.mkdir(parents=True, exist_ok=True)
)
async def tear_down(): async def tear_down():
@ -97,8 +77,14 @@ async def tear_down():
async def init(): async def init():
# init logging
settings = get_settings() settings = get_settings()
dictConfig(settings["logging"]) dictConfig(settings["logging"])
db_path = Path(settings.db_path)
db = MoReDB(db_path) # init storage
url = get_db_url()
if url.scheme == "sqlite":
db = MoReSQLiteDB()
else:
db = MoReDB()
await db.setup() await db.setup()

View File

@ -1,13 +1,27 @@
import logging
from fastapi import FastAPI from fastapi import FastAPI
from tortoise.contrib.pydantic import pydantic_model_creator from tortoise.contrib.pydantic import pydantic_model_creator
from mobilizon_reshare.models.event import Event from mobilizon_reshare.models.event import Event
from mobilizon_reshare.storage.db import init from mobilizon_reshare.storage.db import init as init_db, get_db_url
app = FastAPI() app = FastAPI()
event_pydantic = pydantic_model_creator(Event) event_pydantic = pydantic_model_creator(Event)
logger = logging.getLogger(__name__)
def check_database():
url = get_db_url()
if url.scheme == "sqlite":
logger.warning(
"Database is SQLite. This might create issues when running the web application. Please use a "
"PostgreSQL or MariaDB backend."
)
def register_endpoints(app): def register_endpoints(app):
@app.get("/events", status_code=200) @app.get("/events", status_code=200)
async def get_event(): async def get_event():
@ -17,6 +31,7 @@ def register_endpoints(app):
@app.on_event("startup") @app.on_event("startup")
async def init_app(): async def init_app():
await init() check_database()
await init_db()
register_endpoints(app) register_endpoints(app)
return app return app

17
poetry.lock generated
View File

@ -72,6 +72,19 @@ python-versions = ">=3.6"
[package.dependencies] [package.dependencies]
python-dateutil = ">=2.7.0" python-dateutil = ">=2.7.0"
[[package]]
name = "asyncpg"
version = "0.26.0"
description = "An asyncio PostgreSQL driver"
category = "main"
optional = false
python-versions = ">=3.6.0"
[package.extras]
dev = ["Cython (>=0.29.24,<0.30.0)", "pytest (>=6.0)", "Sphinx (>=4.1.2,<4.2.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "pycodestyle (>=2.7.0,<2.8.0)", "flake8 (>=3.9.2,<3.10.0)", "uvloop (>=0.15.3)"]
docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)"]
test = ["pycodestyle (>=2.7.0,<2.8.0)", "flake8 (>=3.9.2,<3.10.0)", "uvloop (>=0.15.3)"]
[[package]] [[package]]
name = "asynctest" name = "asynctest"
version = "0.13.0" version = "0.13.0"
@ -839,6 +852,7 @@ python-versions = ">=3.7,<4.0"
[package.dependencies] [package.dependencies]
aiosqlite = ">=0.16.0,<0.18.0" aiosqlite = ">=0.16.0,<0.18.0"
asyncpg = {version = "*", optional = true, markers = "extra == \"asyncpg\""}
iso8601 = ">=1.0.2,<2.0.0" iso8601 = ">=1.0.2,<2.0.0"
pypika-tortoise = ">=0.1.6,<0.2.0" pypika-tortoise = ">=0.1.6,<0.2.0"
pytz = "*" pytz = "*"
@ -928,7 +942,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.9" python-versions = "^3.9"
content-hash = "426776ae7c2dc58809693c231cb1f0bb110cbef889131c4718b5a6275e4dfaa6" content-hash = "199b3be9e7cf5adb6ddff51200181f03c9386bcd92dc09bf2c899bb6baa090ce"
[metadata.files] [metadata.files]
aerich = [] aerich = []
@ -946,6 +960,7 @@ arrow = [
{file = "arrow-1.1.1-py3-none-any.whl", hash = "sha256:77a60a4db5766d900a2085ce9074c5c7b8e2c99afeaa98ad627637ff6f292510"}, {file = "arrow-1.1.1-py3-none-any.whl", hash = "sha256:77a60a4db5766d900a2085ce9074c5c7b8e2c99afeaa98ad627637ff6f292510"},
{file = "arrow-1.1.1.tar.gz", hash = "sha256:dee7602f6c60e3ec510095b5e301441bc56288cb8f51def14dcb3079f623823a"}, {file = "arrow-1.1.1.tar.gz", hash = "sha256:dee7602f6c60e3ec510095b5e301441bc56288cb8f51def14dcb3079f623823a"},
] ]
asyncpg = []
asynctest = [ asynctest = [
{file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"}, {file = "asynctest-0.13.0-py3-none-any.whl", hash = "sha256:5da6118a7e6d6b54d83a8f7197769d046922a44d2a99c21382f0a6e4fadae676"},
{file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"}, {file = "asynctest-0.13.0.tar.gz", hash = "sha256:c27862842d15d83e6a34eb0b2866c323880eb3a75e4485b079ea11748fd77fac"},

View File

@ -11,7 +11,7 @@ license = "Coopyleft"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.9" python = "^3.9"
dynaconf = "~3.1" dynaconf = "~3.1"
tortoise-orm = "~0.19" tortoise-orm = {extras = ["asyncpg"], version = "^0.19.2"}
aiosqlite = "~0.17" aiosqlite = "~0.17"
Jinja2 = "~3.1" Jinja2 = "~3.1"
requests = "~2.27" requests = "~2.27"

0
tests/web/__init__.py Normal file
View File

37
tests/web/test_web_db.py Normal file
View File

@ -0,0 +1,37 @@
import logging
import pytest
import urllib3.util
from mobilizon_reshare.web.backend import main
from mobilizon_reshare.web.backend.main import check_database, init_app
def test_check_database_sqlite(caplog):
with caplog.at_level(logging.WARNING):
check_database()
assert caplog.messages == [
"Database is SQLite. This might create issues when running the web application. "
"Please use a PostgreSQL or MariaDB backend."
]
@pytest.mark.asyncio
async def test_check_database_cli(caplog):
with caplog.at_level(logging.WARNING):
await init_app()
assert caplog.messages == [
"Database is SQLite. This might create issues when running the web application. "
"Please use a PostgreSQL or MariaDB backend."
]
@pytest.mark.asyncio
async def test_check_database_postgres(caplog, monkeypatch):
def get_url():
return urllib3.util.parse_url("postgres://someone@something.it")
monkeypatch.setattr(main, "get_db_url", get_url)
with caplog.at_level(logging.WARNING):
check_database()
assert caplog.messages == []