Skip to content

Commit

Permalink
Merge pull request #144 from alice-biometrics/feature/sql-executor-an…
Browse files Browse the repository at this point in the history
…d-multithreading-sql-session-scope

Feature/sql executor and multithreading sql session scope
  • Loading branch information
fgsalomon authored Dec 23, 2020
2 parents e2d8566 + 38da8d3 commit 1948761
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 7 deletions.
6 changes: 3 additions & 3 deletions petisco/persistence/elastic/elastic_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def create_local():
@staticmethod
def from_environ():
return ElasticConnection.create(
os.getenv("ELASTIC_USERNAME", "document-writer"),
os.getenv("ELASTIC_PASSWORD", "document-writer"),
os.getenv("ELASTIC_USERNAME", ""),
os.getenv("ELASTIC_PASSWORD", ""),
os.getenv("ELASTIC_HOST", "localhost"),
os.getenv("ELASTIC_PORT", "443"),
os.getenv("ELASTIC_PORT", "9200"),
)
4 changes: 3 additions & 1 deletion petisco/persistence/sql/mysql/mysql_database.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from typing import List, Callable

from sqlalchemy.orm import scoped_session

from petisco.persistence.interface_database import IDatabase
from petisco.persistence.sql.mysql.mysql_connection import MySqlConnection
from petisco.persistence.persistence_models import PersistenceModels
Expand Down Expand Up @@ -89,7 +91,7 @@ def get_model_names(self) -> List[str]:
return list(self.persistence_models.get_models_names().keys())

def get_session(self):
return self.session_maker()
return scoped_session(self.session_maker)()

def get_session_scope(self) -> Callable:
return sql_session_scope_provider(self.get_session())
28 changes: 28 additions & 0 deletions petisco/persistence/sql/sql_executor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from typing import Callable, List

from sqlalchemy import text


class SqlExecutor:
def __init__(self, session_scope: Callable):
self.session_scope = session_scope

def _get_command(self, statement: str):
command = text(statement.rstrip("\n"))
return command

def execute_from_filename(self, filename: str):
with open(filename) as file:
statements = file.read().split(";")
self.execute_statements(statements)

def execute_statement(self, statement: str):
with self.session_scope() as session:
command = self._get_command(statement)
session.execute(command)

def execute_statements(self, statements: List[str]):
with self.session_scope() as session:
for statement in statements:
command = self._get_command(statement)
session.execute(command)
4 changes: 3 additions & 1 deletion petisco/persistence/sql/sqlite/sqlite_database.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
from typing import List, Callable

from sqlalchemy.orm import scoped_session

from petisco.persistence.interface_database import IDatabase
from petisco.persistence.persistence_models import PersistenceModels
from petisco.persistence.sql.sql_session_scope_provider import (
Expand Down Expand Up @@ -83,7 +85,7 @@ def get_model_names(self) -> List[str]:
return list(self.persistence_models.get_models_names().keys())

def get_session(self):
return self.session_maker()
return scoped_session(self.session_maker)()

def get_session_scope(self) -> Callable:
return sql_session_scope_provider(self.get_session())
2 changes: 2 additions & 0 deletions petisco/public_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@
from petisco.persistence.sql.mysql.mysql_connection import MySqlConnection
from petisco.persistence.sql.mysql.mysql_database import MySqlDatabase
from petisco.persistence.sql.sql_repository import SqlRepository
from petisco.persistence.sql.sql_executor import SqlExecutor

sql = [
"SqlAlchemyPersistence",
Expand All @@ -288,6 +289,7 @@
"MySqlConnection",
"MySqlDatabase",
"SqlRepository",
"SqlExecutor",
]
except (RuntimeError, ImportError):
sql = []
Expand Down
2 changes: 1 addition & 1 deletion petisco/security/token_manager/jwt_token_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ def build(
"cli": client_id.value,
"sub": user_id.value if user_id else None,
}
token = jwt.encode(payload, key, algorithm="RS256").decode("utf-8")
token = jwt.encode(payload, key, algorithm="RS256")
return token
2 changes: 1 addition & 1 deletion requirements/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requests==2.24.0
dataclasses==0.7;python_version<"3.7"
dataclasses-json==0.5.2
backports-datetime-fromisoformat>=1.0.0;python_version<"3.7"
pyjwt>=1.7.1
pyjwt==2.0.0
cryptography>=2.1.4
py-healthcheck==1.7.2
APScheduler==3.6.3
Expand Down
62 changes: 62 additions & 0 deletions tests/modules/persistence/integration/test_sql_executor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import pytest

from petisco import SqliteDatabase, SqliteConnection, Persistence, SqlExecutor
from tests.modules.persistence.mother.model_filename_mother import ModelFilenameMother


@pytest.mark.integration
def test_should_sql_executor_insert_statement():
filename = ModelFilenameMother.get("sql/persistence.sql.models.yml")
connection = SqliteConnection.create(
server_name="sqlite", database_name="petisco.db"
)
database = SqliteDatabase(
name="sqlite_test", connection=connection, model_filename=filename
)

persistence = Persistence()
persistence.add(database)
persistence.create()

session_scope = Persistence.get_session_scope("sqlite_test")
sql_executor = SqlExecutor(session_scope)

sql_executor.execute_statement(
'INSERT INTO Client (client_id,name) VALUES ("65dd83ef-d315-417d-bfa8-1ab398e16f02","myclient")'
)
sql_executor.execute_statement(
'DELETE FROM Client WHERE client_id=="65dd83ef-d315-417d-bfa8-1ab398e16f02";'
)

persistence.clear_data()
persistence.delete()
Persistence.clear()


@pytest.mark.integration
def test_should_sql_executor_from_filename_with_statement():
filename = ModelFilenameMother.get("sql/persistence.sql.models.yml")
connection = SqliteConnection.create(
server_name="sqlite", database_name="petisco.db"
)
database = SqliteDatabase(
name="sqlite_test", connection=connection, model_filename=filename
)

persistence = Persistence()
persistence.add(database)
persistence.create()

session_scope = Persistence.get_session_scope("sqlite_test")
sql_executor = SqlExecutor(session_scope)

sql_executor.execute_from_filename(
"tests/modules/persistence/sql/client_create.sql"
)
sql_executor.execute_from_filename(
"tests/modules/persistence/sql/client_delete.sql"
)

persistence.clear_data()
persistence.delete()
Persistence.clear()
2 changes: 2 additions & 0 deletions tests/modules/persistence/sql/client_create.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
INSERT INTO Client (client_id,name) VALUES ("65dd83ef-d315-417d-bfa8-1ab398e16f02","myclient-bad");
UPDATE Client SET name="myclient" WHERE client_id="65dd83ef-d315-417d-bfa8-1ab398e16f02"
1 change: 1 addition & 0 deletions tests/modules/persistence/sql/client_delete.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DELETE FROM Client WHERE name=="myclient"

0 comments on commit 1948761

Please sign in to comment.