Как передать переменные в f-строки соседнего скрипта?

Мой проект состоит из нескольких скриптов:

  1. main.py

    from dbconnect import execute_from_db  
    if __name__ == '__main__':  
        x = '2022-05-25'     
        y = '2022-06-01'   
        execute_data = execute_from_db()
    
  2. dbconnect.py Для подключения к БД, получения результатов запросов из sql_code.py

    import sql_code  
    def execute_from_db():  
        con = pymysql.connect(host=host, user=db_user, password=db_password, database=database)  
        with con:  
            cur = con.cursor()  
            cur.execute(sql_code.all) 
        return cur.fetchall()
    
  3. sql_code.py Содержит запросы к БД в виде f-строк

    all = "SELECT * " \
          "FROM jiraissue ji " \
          f"WHERE ji.created > '{x}' " \
          f"AND ji.created < '{y}') " 
    

Как-то возможно передать переменные из main.py в f-строки sql_code.py или я составил некорректную структуру проекта? Как можно лучше организовать данный функционал(чтобы запросы хранились отдельно от кода подключения к БД и динамически менялись в зависимости от введенных в main.py параметров)?


Ответы (1 шт):

Автор решения: insolor
  1. Используйте параметры функции для передачи x, y в функцию execute_from_db

  2. Внутри функции execute_from_db подставляйте параметры средствами SQL библиотеки. Лучше сверяться с документацией, т.к. синтаксис может различаться. Для pymysql смотрите пример здесь: https://pymysql.readthedocs.io/en/latest/user/examples.html

    Не используйте f-строки и другие способы форматирования для подстановки параметров SQL запросов - это делает ваш код потенциально подверженным SQL инъекциям.

    Предположим, даты у вас берутся из http запроса. Злоумышленник может выполнить свой запрос, подставив вместо даты кусок SQL кода, который, например, удалит у вас базе парочку "ненужных" таблиц.

    К прочтению: Как правильно подставлять значения из переменных / списков / словарей в SQL запрос?

  3. Если очень хочется (не для SQL запросов) - используйте метод format.

    Подставлять в f-строку так как вы хотите не получится - f-строка у вас получает свое фактическое значение в момент импорта вашего модуля (в момент "выполнения" f-строки). Можно обернуть f-строку в функцию, но проще использовать более "старое" средство форматирования строк - метод format.

from dbconnect import execute_from_db  
if __name__ == '__main__':  
    x = '2022-05-25'     
    y = '2022-06-01'   
    execute_data = execute_from_db(x, y)
import sql_code  
def execute_from_db(x, y):  
    con = pymysql.connect(host=host, user=db_user, password=db_password, database=database)  
    with con:  
        cur = con.cursor()  
        cur.execute(sql_code.all, (x, y)) 
    return cur.fetchall()
all = "SELECT * " \
        "FROM jiraissue ji " \
        "WHERE ji.created > %s " \
        "AND ji.created < %s " 

Подстановка значений в строку с помощью метода format:

import some_strings

name = input("Введите ваше имя:")
print(some_strings.greeting.format(name=name))

some_strings.py:

greeting = "Привет, {name}!"  # Обычная строка (не f-строка)
→ Ссылка