Estoy tratando de encontrar la mejor manera de formatear una cadena de consulta SQL. Cuando estoy depurando mi aplicación, me gustaría iniciar sesión para archivar todas las cadenas de consulta SQL, y es importante que la cadena esté formateada correctamente.
Opción 1
def myquery():
sql = "select field1, field2, field3, field4 from table where condition1=1 and condition2=2"
con = mymodule.get_connection()
...
- Esto es bueno para imprimir la cadena sql.
- No es una buena solución si la cadena es larga y no se ajusta al ancho estándar de 80 caracteres.
opcion 2
def query():
sql = """
select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
con = mymodule.get_connection()
...
Aquí el código es claro, pero cuando imprime la cadena de consulta SQL, obtiene todos estos molestos espacios en blanco.
u '\ nseleccionar campo1, campo2, campo3, campo4 \ n_ _ ___ de la tabla \ n _ ___ donde condición1 = 1 \ n _ ___ _ y condición2 = 2'
Nota: he reemplazado los espacios en blanco con un guión bajo _
, porque el editor los recorta
Opción 3
def query():
sql = """select field1, field2, field3, field4
from table
where condition1=1
and condition2=2"""
con = mymodule.get_connection()
...
- No me gusta esta opción porque rompe la claridad del código bien tabulado.
Opción 4
def query():
sql = "select field1, field2, field3, field4 " \
"from table " \
"where condition1=1 " \
"and condition2=2 "
con = mymodule.get_connection()
...
- No me gusta esta opción porque toda la escritura adicional en cada línea y también es difícil editar la consulta.
Para mí la mejor solución sería la Opción 2 pero no me gustan los espacios en blanco adicionales cuando imprimo la cadena sql.
¿Conoces otras opciones?
fuente
Respuestas:
Perdón por publicar en un hilo tan antiguo, pero como alguien que también comparte la pasión por lo 'mejor' pitónico, pensé en compartir nuestra solución.
La solución es construir declaraciones SQL usando la Concatenación de Literal de Cadena de Python ( http://docs.python.org/ ), que podría calificarse en algún lugar entre la Opción 2 y la Opción 4
Ejemplo de código:
Funciona también con f-strings :
Pros:
fuente
"""
y usartextwrap.dedent()
antes de la salida"sql query"
para evitar jugar con cadenas SQL (que usan comillas simples como estándar)?Obviamente, ha considerado muchas formas de escribir el SQL de manera que se imprima bien, pero ¿qué tal cambiar la declaración 'imprimir' que usa para el registro de depuración, en lugar de escribir su SQL de formas que no le gustan? Usando su opción favorita anterior, ¿qué tal una función de registro como esta:
Esto también haría que sea trivial agregar lógica adicional para dividir la cadena registrada en varias líneas si la línea es más larga que la longitud deseada.
fuente
La forma más limpia con la que me he encontrado está inspirada en la guía de estilo sql .
Esencialmente, las palabras clave que comienzan una cláusula deben estar alineadas a la derecha y los nombres de los campos, etc., deben estar alineados a la izquierda. Esto se ve muy ordenado y también es más fácil de depurar.
fuente
si el valor de la condición debe ser una cadena, puede hacer lo siguiente:
fuente
format()
cadenas SQL, es un olor a código importante.where condition1=:field1
y luego pasar los valores como parámetros. Si está utilizando.format()
, habrá una forma de';DROP TABLE Users
introducir un en su SQL. Eche un vistazo a PEP-249 para saber cómo utilizar los parámetros correctamente. python.org/dev/peps/pep-0249/#paramstylePara evitar el formateo por completo , creo que una gran solución es utilizar procedimientos .
Llamar a un procedimiento le da el resultado de cualquier consulta que desee poner en este procedimiento. De hecho, puede procesar varias consultas dentro de un procedimiento. La llamada simplemente devolverá la última consulta que se llamó.
MYSQL
Pitón
fuente
podría poner los nombres de los campos en una matriz "campos", y luego:
fuente
Sugeriría ceñirse a la opción 2 (siempre la uso para consultas más complejas que
SELECT * FROM table
) y si desea imprimirla de una manera agradable, siempre puede usar un módulo separado .fuente
Para consultas cortas que pueden caber en una o dos líneas, uso la solución literal de cadena en la solución más votada anterior. Para consultas más largas, las divido en
.sql
archivos. Luego uso una función contenedora para cargar el archivo y ejecutar el script, algo como:Por supuesto, esto a menudo vive dentro de una clase, por lo que generalmente no tengo que aprobar
cursor
explícitamente. También uso generalmentecodecs.open()
, pero esto hace que la idea general se entienda. Entonces, los scripts SQL son completamente autónomos en sus propios archivos con su propia sintaxis resaltada.fuente
[editar en responder al comentario]
Tener una cadena SQL dentro de un método NO significa que tenga que "tabularlo":
fuente
select
. Mi respuesta no tiene espacios iniciales. ¿Qué le llevó a formarse la opinión de que son iguales?