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 테이블에서 field1, field2, field3, field4 \ n_ _ ___ 선택 \ n _ ___ where condition1 = 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 문자열을 인쇄 할 때 추가 공백이 마음에 들지 않습니다.
다른 옵션을 알고 있습니까?
그런 오래된 스레드에 게시 해 주셔서 죄송합니다.하지만 비단뱀 같은 '최고'에 대한 열정을 공유하는 사람으로서 저는 우리의 솔루션을 공유 할 것이라고 생각했습니다.
해결책은 python의 String Literal Concatenation ( http://docs.python.org/ )을 사용하여 SQL 문을 빌드 하는 것입니다. 이는 옵션 2와 옵션 4 사이의 어딘가에 자격을 부여 할 수 있습니다.
코드 샘플 :
sql = ('select field1, field2, field3, field4 '
'from table '
'where condition1=1 '
'and condition2=2 ')
장점 :
- 비단뱀의 '잘 표로 만들어진'형식을 유지하지만 불필요한 공백 문자를 추가하지 않습니다 (로깅을 오염시킵니다).
- 옵션 4의 백 슬래시 연속 추악함을 피하여 문을 추가하기 어렵게 만듭니다 (공백 블라인드는 말할 것도 없음).
- 또한 VIM에서 명령문을 확장하는 것은 정말 간단합니다 (커서를 삽입 지점에 놓고 SHIFT-O 를 눌러 새 줄을 엽니 다).
SQL이 제대로 출력되도록 작성하는 많은 방법을 분명히 고려했지만, 원하지 않는 방식으로 SQL을 작성하는 대신 디버그 로깅에 사용하는 'print'문을 변경하는 것은 어떻습니까? 위에서 좋아하는 옵션을 사용하여 다음과 같은 로깅 기능은 어떻습니까?
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)
이렇게하면 줄이 원하는 길이보다 길면 로깅 된 문자열을 여러 줄로 분할하는 추가 논리를 추가하는 것도 간단합니다.
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'
condition의 값이 문자열이어야하는 경우 다음과 같이 할 수 있습니다.
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'"
내가 본 가장 깨끗한 방법은 SQL 스타일 가이드 에서 영감을 얻었습니다 .
sql = """
SELECT field1, field2, field3, field4
FROM table
WHERE condition1 = 1
AND condition2 = 2;
"""
기본적으로 절을 시작하는 키워드는 오른쪽 정렬되어야하고 필드 이름 등은 왼쪽 정렬되어야합니다. 이것은 매우 깔끔하게 보이며 디버그하기도 더 쉽습니다.
필드 이름을 배열 "필드"에 넣은 다음 다음을 수행 할 수 있습니다.
sql = 'select %s from table where condition1=1 and condition2=2' % (
', '.join(fields))
옵션 2를 고수하는 것이 좋습니다 (항상 더 복잡한 쿼리에 사용하고 있습니다 SELECT * FROM table
). 좋은 방법으로 인쇄하려면 항상 별도의 모듈을 사용할 수 있습니다 .
For short queries that can fit on one or two lines, I use the string literal solution in the top-voted solution above. For longer queries, I break them out to .sql
files. I then use a wrapper function to load the file and execute the script, something like:
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)
Of course this often lives inside a class so I don't usually have to pass cursor
explicitly. I also generally use codecs.open()
, but this gets the general idea across. Then SQL scripts are completely self-contained in their own files with their own syntax highlighting.
In Addition to @user590028 :
Using format was helpful for what I was working on like so:
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"
)
And:
statement = ("INSERT INTO product_product "
"(product_tmpl_id,default_code,active,valuation) "
"VALUE "
"('{0}','{1}',True,'manual_periodic')".format(str(row[0]), row[1])
)
To avoid formatting entirely, I think a great solution is to use procedures.
Calling a 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 will just return the last query that was called.
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;
Python
sql =('call example;')
sql = """\
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2
"""
[edit in responese to comment]
Having an SQL string inside a method does NOT mean that you have to "tabulate" it:
>>> class Foo:
... def fubar(self):
... sql = """\
... select *
... from frobozz
... where zorkmids > 10
... ;"""
... print sql
...
>>> Foo().fubar()
select *
from frobozz
where zorkmids > 10
;
>>>
참고URL : https://stackoverflow.com/questions/5243596/python-sql-query-string-formatting
'code' 카테고리의 다른 글
부트 스트랩의 tabindex =“-1”은 무엇입니까? (0) | 2020.10.10 |
---|---|
다중 모듈 프로젝트의 Maven 테스트 종속성 (0) | 2020.10.10 |
콘솔을 어떻게 지울 수 있습니까? (0) | 2020.10.10 |
Java hashMap 내용을 서로 다른 내용에 넣지 만 기존 키와 값을 바꾸지 않는 방법은 무엇입니까? (0) | 2020.10.10 |
Maven : 인수를 전달하는 명령 줄에서 .java 파일을 실행하는 방법 (0) | 2020.10.10 |