[英]How do you create a table in mysql using SQLalchemy with a spatial column?
[英]How to test mysql queries using sqlalchemy and sqlite?
我有以下用Python3.6編寫的代碼結構,我需要使用sqlite3進行測試(由於我的項目中定義了標准):
class BigSecretService:
""" Class designed to make calculations based on data stored in MySQL. """
def load_data(self):
# load some data using sqlalchemy ORM
def get_values_from_fields(self, fields):
# here's getting values via sqlalchemy execute with raw query:
self.sql_service.execute(SOME_QUERY)
def process_data(self, data, values):
# again execute some raw query
# process data and put into result list
return reuslt_list
def make_calculations(self, params):
data = self.load_data()
values = self.get_values_from_fields(fields)
result_vector = process_data(data, values)
SOME_QUERY在單獨的模塊中,其格式如下所示:
"SELECT SUM(some_field) FROM some_table WHERE col1 = :col1 AND col2 = :col2"
為了在我的組件測試中介紹make_calculations,我設計了一些糟糕的補丁:
class PatchedConnection:
""" Class is used to transform queries to sqlite format before executing. """
def __init__(self, connection, engine):
self.connection = connection
self.engine = engine
def __call__(self):
conn = self.connection()
conn.execute = self.patched_execute(conn.execute)
return conn
def transform_date(self, date):
try:
# quick check just for testing
if '+00:00' in date:
date = date.replace('T', ' ').replace('+00:00', '.000000')
finally:
return date
def patched_execute(self, f_execute):
def prepare_args_for_sqlite(query, *args):
# check if query is in sqlite format
if args:
if '?' in str(query):
args = list(map(self.transform_date, list(args[0].values())))
return self.engine.execute(str(query), args)
return f_execute(query, args[0])
else:
return f_execute(query)
return prepare_args_for_sqlite
然后在測試中看起來像這樣:
QUERY_TEMPLATE_SQLITE = 'SELECT SUM(some_field) FROM some_table WHERE col1 = ? AND col2 = ?'
with mock.patch('path_to_my_service.SOME_QUERY', QUERY_TEMPLATE_SQLITE):
self.sql_service.get_connection = PatchedConnection(self.sql_service.get_connection, self.engine)
response = self.client.simulate_post("/v1/secret_service/make_calculations",
headers=self.auth_header,
body=json.dumps(payload))
self.assertEqual(response.status_code, 200)
# then check response.text
到目前為止,它仍然有效,但是我相信必須有更好的解決方案。 而且,在dict中的patched_execute參數中,args被轉換為list,誰知道dict值的順序是否始終相同。 因此,我的問題是如何使用給定的工具以正確的方式執行此類測試?
如果您需要攔截和處理發送到數據庫的SQL,則使用核心事件https://docs.sqlalchemy.org/en/13/core/events.html將是最簡單的方法。 如SQLAlchemy文檔的以下示例中所述, before_cursor_execute
事件將滿足您的目的。
@event.listens_for(engine, "before_cursor_execute", retval=True)
def before_cursor_execute(conn, cursor, statement, parameters, context, executemany):
# do something with statement, parameters
return statement, parameters
但是,從您給出的示例中,我不確定是否有必要這樣做。 您列出的MySQL查詢也是有效的SQLite查詢,不需要任何操作。 同樣,如果您將參數作為python對象而不是字符串進行傳遞,則同樣無需進行任何操作,因為SQLAlchemy會將其正確映射到后端。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.