Подтвердить что ты не робот

Форматирование строки запроса Python SQL

Я пытаюсь найти лучший способ форматирования строки запроса sql. Когда я отлаживаю мое приложение, которое я хотел бы зарегистрировать, чтобы записать все строки запроса sql, и это важно, чтобы строка была правильно сформирована.

Вариант 1

def myquery():
    sql = "select field1, field2, field3, field4 from table where condition1=1 and condition2=2"
    con = mymodule.get_connection()
    ...
  • Это полезно для печати строки sql.
  • Это нехорошее решение, если строка длинная и не соответствует стандартной ширине 80 символов.

Вариант 2

def query():
    sql = """
        select field1, field2, field3, field4
        from table
        where condition1=1
        and condition2=2"""
    con = mymodule.get_connection()
    ...
  • Здесь код ясен, но когда вы печатаете строку запроса sql, вы получаете все эти раздражающие пробелы.

    u '\nизбрать поле1, поле2, поле3, поле4\n_ ____ из таблицы \n ____, где условие1 = 1\n ____ _and condition2 = 2 '

Примечание. Я заменил белые пробелы символом подчеркивания _, потому что они обрезаны редактором

Вариант 3

def query():
    sql = """select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
    con = mymodule.get_connection()
    ...
  • Мне не нравится этот параметр, потому что он нарушает ясность кода с таблицей с таблицей.

Вариант 4

def query():
    sql = "select field1, field2, field3, field4 " \
          "from table " \
          "where condition1=1 " \
          "and condition2=2 "
    con = mymodule.get_connection()    
    ...
  • Мне не нравится этот параметр, потому что все дополнительные ввода в каждой строке и также трудно редактировать запрос.

Для меня лучшим решением будет Вариант 2, но мне не нравятся лишние пробелы при печати строки sql.

Знаете ли вы какие-либо другие варианты?

4b9b3361

Ответ 1

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

Решение состоит в том, чтобы создавать инструкции SQL, используя python String Literal Concatenation (http://docs.python.org/), который может быть квалифицирован где-то между Вариантом 2 и Вариантом 4

Пример кода:

sql = ('select field1, field2, field3, field4 '
       'from table '
       'where condition1=1 '
       'and condition2=2 ')

Плюсы:

  • Он сохраняет питонический "хорошо подобранный" формат, но не добавляет лишние символы пробела (который загрязняет ведение журнала).
  • Это позволяет избежать упущения продолжения обратной косой черты Варианта 4, что затрудняет добавление утверждений (не говоря уже о слепоте белого пространства).
  • И еще, очень просто расширить оператор в VIM (просто поместите курсор в точку вставки и нажмите SHIFT-O, чтобы открыть новую строку).

Ответ 2

Вы, очевидно, рассмотрели множество способов написания SQL, чтобы он печатался в порядке, но как насчет изменения инструкции print, которую вы используете для ведения журнала отладки, вместо того, чтобы писать свой SQL так, как вам не нравится? Используя ваш любимый вариант выше, как насчет функции ведения журнала, например:

def debugLogSQL(sql):
     print ' '.join([line.strip() for line in sql.splitlines()]).strip()

sql = """
    select field1, field2, field3, field4
    from table"""
if debug:
    debugLogSQL(sql)

Это также упростит добавление дополнительной логики, чтобы разделить записанную строку на несколько строк, если длина строки больше требуемой длины.

Ответ 3

Самый чистый способ, с которым я столкнулся, вдохновлен руководством по стилю sql.

sql = """
    SELECT field1, field2, field3, field4
      FROM table
     WHERE condition1 = 1
       AND condition2 = 2;
"""

По сути, ключевые слова, которые начинают предложение, должны быть выровнены по правому краю, а имена полей и т.д. Должны быть выровнены по левому краю. Это выглядит очень аккуратно, и его легче отлаживать.

Ответ 4

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1={} "
       "and condition2={}").format(1, 2)

Output: 'select field1, field2, field3, field4 from table 
         where condition1=1 and condition2=2'

если значение условия должно быть строкой, вы можете сделать следующее:

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1='{0}' "
       "and condition2='{1}'").format('2016-10-12', '2017-10-12')

Output: "select field1, field2, field3, field4 from table where
         condition1='2016-10-12' and condition2='2017-10-12'"

Ответ 5

вы можете поместить имена полей в "поля" массива, а затем:


sql = 'select %s from table where condition1=1 and condition2=2' % (
 ', '.join(fields))

Ответ 6

sql = """\
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2
"""

[edit in responese to comment]
Наличие строки SQL внутри метода НЕ означает, что вы должны "табулировать" его:

>>> class Foo:
...     def fubar(self):
...         sql = """\
... select *
... from frobozz
... where zorkmids > 10
... ;"""
...         print sql
...
>>> Foo().fubar()
select *
from frobozz
where zorkmids > 10
;
>>>

Ответ 7

Я бы посоветовал придерживаться варианта 2 (я всегда использую его для запросов, более сложных, чем SELECT * FROM table), и если вы хотите напечатать его красивым способом, вы всегда можете использовать отдельный модуль.

Ответ 8

Для коротких запросов, которые могут вписываться в одну или две строки, я использую решение строкового литерала в вышеперечисленном выше решении. Для более длинных запросов я разбиваю их на .sql файлы. Затем я использую функцию-оболочку для загрузки файла и выполняю script, что-то вроде:

script_cache = {}
def execute_script(cursor,script,*args,**kwargs):
    if not script in script_cache:
        with open(script,'r') as s:
            script_cache[script] = s
    return cursor.execute(script_cache[script],*args,**kwargs)

Конечно, это часто живет внутри класса, поэтому я обычно не должен явно пропускать cursor. Я также обычно использую codecs.open(), но это дает общую идею. Затем SQL-скрипты полностью автономны в своих файлах с подсветкой синтаксиса.

Ответ 9

В дополнение к @user590028:

Использование формата было полезно для того, над чем я работал:

statement = (ins
            "(name,standard_price,list_price,mes_type,uom_id,uom_po_id,type,procure_method,cost_method_categ_id,supply_method,sale_ok) "
            "VALUE ('{0}','{1}','{2}'".format(row[1],str(row[2]),str(row[2])) + ",'fixed',1,1,'product','make_to_stock','standard',1,'buy',True) RETURNING id"
            )

и

statement = ("INSERT INTO product_product "
             "(product_tmpl_id,default_code,active,valuation) "
             "VALUE "
             "('{0}','{1}',True,'manual_periodic')".format(str(row[0]), row[1])
             )

Ответ 10

Я бы предложил очень простой вариант. просто поставьте r перед строкой. Вы можете использовать его, как показано ниже:

query=(r'SELECT f1,f2,f3 '
     r'FROM table1 '
     r'WHERE f4=cond1 '
     r'AND f5=cond2 ')
cursor.execute(str(query))
results=cursor.fetchall()
cursor.close()

Ответ 11

Чтобы полностью избежать форматирования, я думаю, что хорошим решением является использование процедур.

Вызов процедуры дает вам результат любого запроса, который вы хотите поместить в эту процедуру. Вы можете обрабатывать несколько запросов в рамках одной процедуры. Вызов просто вернет последний запрос, который был вызван.

MYSQL

DROP PROCEDURE IF EXISTS example;
 DELIMITER //
 CREATE PROCEDURE example()
   BEGIN
   SELECT 2+222+2222+222+222+2222+2222 AS this_is_a_really_long_string_test;
   END //
 DELIMITER;

#calling the procedure gives you the result of whatever query you want to put in this procedure. You can actually process multiple queries within a procedure. The call just returns the last query result
 call example;

питон

sql =('call example;')