This repository has been archived by the owner on Dec 19, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
BaseSQL.py
131 lines (107 loc) · 3.55 KB
/
BaseSQL.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from abc import ABC, abstractmethod
from contextlib import contextmanager
from typing import List
import sqlalchemy as sa
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, BigInteger, Text, Float, Boolean
from sqlalchemy.sql import func
from sqlalchemy import or_, and_
from sqlalchemy_utils import create_database, database_exists
from sqlalchemy import text
from sqlalchemy import Index, Table
from PyStorageTexts.BaseAPI import BaseAPI
from PyStorageHelpers import *
DeclarativeDocsSQL = declarative_base()
class TextSQL(DeclarativeDocsSQL):
__tablename__ = 'table_texts'
_id = Column(BigInteger, primary_key=True)
content = Column(Text)
content_index = Index('content_index', TextSQL.content, unique=False)
def __init__(self, *args, **kwargs):
DeclarativeDocsSQL.__init__(self)
class BaseSQL(BaseAPI):
"""
A generic SQL-compatiable wrapper for Textual data.
It's built on top of SQLAlchemy which supports following engines:
* SQLite,
* PostgreSQL,
* MySQL,
* Oracle,
* MS-SQL,
* Firebird,
* Sybase.
"""
__is_concurrent__ = True
__in_memory__ = False
# --------------------------------
# region Initialization and Metadata.
# --------------------------------
def __init__(self, url='sqlite:///:memory:', **kwargs):
BaseAPI.__init__(self, **kwargs)
# https://stackoverflow.com/a/51184173
if not database_exists(url):
create_database(url)
self.engine = sa.create_engine(url)
DeclarativeDocsSQL.metadata.create_all(self.engine)
self.session_maker = sessionmaker(bind=self.engine)
@contextmanager
def get_session(self):
session = self.session_maker()
session.expire_on_commit = False
try:
yield session
session.commit()
except Exception as doc:
print(doc)
session.rollback()
raise doc
finally:
session.close()
def count_texts(self) -> int:
result = 0
with self.get_session() as s:
result = s.query(TextSQL).count()
return result
# endregion
# --------------------------------
# region Adding and removing documents.
# --------------------------------
def upsert_text(self, doc: TextSQL) -> bool:
result = False
with self.get_session() as s:
s.merge(doc)
result = True
return result
def remove_text(self, doc: TextSQL) -> bool:
result = False
with self.get_session() as s:
s.query(TextSQL).filter_by(
_id=doc._id
).delete()
result = True
return result
def upsert_texts(self, docs: List[Edge]) -> int:
result = 0
with self.get_session() as s:
docs = list(map(s.merge, docs))
result = len(docs)
return result
def clear(self) -> int:
result = 0
with self.get_session() as s:
result += s.query(TextSQL).delete()
return result
# endregion
# --------------------------------
# region Search Queries.
# --------------------------------
@abstractmethod
def find_substring(self, field: str, query: str) -> Sequence[Text]:
pass
@abstractmethod
def find_regex(self, field: str, query: str) -> Sequence[Text]:
pass
def get(self, identifier: str) -> object:
pass
# endregion