Как использовать пустую строку в запросе SQL при использовании Python - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть запрос PostgreSQL, который не выполняется должным образом, когда я ищу пустые строки.Я пробовал экранировать одинарные кавычки с обратной косой чертой, пробовал двойные кавычки, похоже, ничего не работает.Идеи?Мне нужно искать пустые строки, потому что мой скрипт не делает то, что мне нужно, когда он находит пустые строки в моем наборе данных.

this_query = """
copy(SELECT phone_number from mytable WHERE phone_number is not null and phone_number != '''' ORDER BY random() LIMIT 25)
to stdout csv header;
"""

Без фразы пустой строки (phone_number! = '' ''), запрос будет работать, когда я выполню:

THIS_COMMAND = "psql -h hostname -d dbname -c '{query}' > {file_name}"

command = THIS_COMMAND.format(query=this_query, file_name=a_file_name)

os.system(command)

ВНИМАНИЕ: После просмотра ответов ниже я экспериментировал и обнаружил, что это работает:

phone_number != '\"'\"''\"'\"' 

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Рассмотрим встроенный в Python subprocess для передачи нескольких аргументов в вызов командной строки и избежания необходимости заключать в кавычки или экранировать.Это более расширенный вызов командной строки, чем os.system().Кроме того, как показано ниже, вы можете установить переменные окружения, такие как PGPASSWORD.

В частности, используйте команду мета-команды psql \copy (в отличие от Postgres 'COPY), чтобы передать файл непосредственно в имя запроса, чтобысохранено на стороне клиента.Также обратите внимание на использование r (необработанный строковый литерал), поэтому обратную косую черту в \copy можно обрабатывать как есть, а не как специальный символ.

from subprocess import Popen, PIPE

file_name = '/path/to/file.csv'

this_query = r"""\copy (SELECT phone_number 
                        FROM mytable 
                        WHERE phone_number is not null 
                          AND phone_number != ''
                        ORDER BY random() LIMIT 25)
             TO '{myfile}' with (FORMAT CSV, HEADER);
             """.format(file_name)

host_name = 'XX.XX.XXX'
db_name = 'mydatabase'
user_name = 'myuser'
pwd = 'mypwd'

# LIST OF ARGS
cmd = ["psql", "-h", host_name,  "-d", db_name, 
       "-U", user_name, "-p", "5432", "-c", this_query]

# COMMAND LINE CALL
p = Popen(cmd, env={'PGPASSWORD': pwd},
          stdin=PIPE, stdout=PIPE, stderr=PIPE)

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

output, error = p.communicate()

if p.returncode == 0:            
    print('OUTPUT:\n {0}'.format(output))            
    print("\nSuccessfully completed!")
else:                
    print('ERROR:\n {0}'.format(error)) 
0 голосов
/ 19 декабря 2018

Есть способы заставить это работать с кавычками.

РЕДАКТИРОВАТЬ: Перекрестные ссылки этот ответ цитирования оболочки UNIX : Кавычки должны быть экранированы для Python и sh / bash (предположительно).Таким образом, для sh это должно быть '"'"''"'"', но тогда для Python необходимо экранировать символы ", что дает '\"'\"''\"'\"'.Фу!

this_query = """
copy(SELECT phone_number from mytable WHERE phone_number is not null and phone_number != '\"'\"''\"'\"''\"'\"''\"'\"' ORDER BY random() LIMIT 25) to stdout csv header;
"""

Но чтобы дать другой подход, вы рассматривали возможность проверки character_length(phone_number) > 0?

Ссылка: https://www.postgresql.org/docs/9.1/functions-string.html

Например:

SELECT phone_number FROM mytable WHERE phone_number IS NOT NULL AND character_length(phone_number) > 0

Но может быть, лучше очистить данные?

UPDATE mytable SET phone_number = NULL WHERE character_length(trim(phone_number)) = 0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...