Я написал сценарий, который использует функцию потоковой обработки python. Я думаю, что проблема имеет какое-то отношение к потоковой передаче, потому что, когда я запускаю запрос из-за рабочего потока, он отлично работает. Я пытаюсь вставить некоторые вещи в базу данных, но столкнулся с некоторыми ДЕЙСТВИТЕЛЬНО фанковыми поведением.Python - Postgresql Неверная последовательность байтов для varchar - Weird Behavior
Позвольте мне упростить:
Запуск это работает:
cmd = "INSERT INTO cstanley_temp (device, host, ux, units) VALUES (%s, %s, %s, %s);"
data = ("solaris-cdc", resultHOST[0], "UX10", 1,)
sql.execute(cmd, data)
Бегущий это не работает:
cmd = "INSERT INTO cstanley_temp (device, host, ux, units) VALUES (%s, %s, %s, %s);"
data = ("solaris-cdc", resultHOST[0], "sdsdsdsdsdsd", 1,)
sql.execute(cmd, data)
Вот типы полей: device
= VARCHAR host
= VARCHAR ux
= varchar units
= INT
Это ошибка я получаю:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/local/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/cstanley/scripts/vip/sun_audit.py", line 37, in workon
sql.execute(cmd, data)
DataError: invalid byte sequence for encoding "UTF8": 0x86
HINT: This error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
Exception in thread Thread-2:
Traceback (most recent call last):
File "/usr/local/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/local/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/cstanley/scripts/vip/sun_audit.py", line 37, in workon
sql.execute(cmd, data)
InternalError: current transaction is aborted, commands ignored until end of transaction block
Вот полный код:
#!/usr/local/bin/python2.7
import sys, os, string, threading
import paramiko
import psycopg2
import time
#paramiko.util.log_to_file("sun_audit.log")
getCPU = "/usr/sbin/psrinfo -p"
getMEM = "/usr/sbin/prtconf | grep \"Memory\" | awk '{ print $3 }'"
getHOST = "hostname"
class bcolors:
MAGENTA = '\033[95m'
YELLOW = '\033[93m'
ENDC = '\033[0m'
def workon(host,sql):
#Connect to each host
ssh = paramiko.SSHClient()
key = paramiko.RSAKey.from_private_key_file("/home/cstanley/scripts/vip/cstanley")
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(host, username='cstanley', pkey=key)
#Run Commands
stdinHOST, stdoutHOST, stderrHOST = ssh.exec_command(getHOST)
stdinCPU, stdoutCPU, stderrCPU = ssh.exec_command(getCPU)
stdinMEM, stdoutMEM, stderrMEM = ssh.exec_command(getMEM)
with threading.Lock():
resultHOST = stdoutHOST.readlines()
#print "{0} {0} UX10 1".format(resultHOST[0].rstrip())
cmd = "INSERT INTO cstanley_temp (device, host, ux, units) VALUES (%s, %s, %s, %s);"
data = ("solaris-cdc", resultHOST[0], "sdsdsdsdsdsd", 1,)
sql.execute(cmd, data)
resultCPU = stdoutCPU.readlines()
ux40 = (int(resultCPU[0].rstrip()) - 1)
if ux40 != 0:
#print "{0} {0} UX40 {1}".format(resultHOST[0].rstrip(),ux40)
cmd = "INSERT INTO cstanley_temp (device, host, ux, units) VALUES (%s, %s, %s, %s);"
data = ("solaris-cdc", resultHOST[0], "UX40", ux40,)
sql.execute(cmd, data)
resultMEM = stdoutMEM.readlines()
ux30 = (int(resultMEM[0].rstrip())/1024 - 2)/2
#print "{0} {0} UX30 {1}".format(resultHOST[0].rstrip(),ux30)
cmd = "INSERT INTO cstanley_temp (device, host, ux, units) VALUES (%s, %s, %s, %s);"
data = ("solaris-cdc", resultHOST[0], "UX30", ux30,)
sql.execute(cmd, data)
ssh.close()
def main():
#date = (time.strftime("%Y-%m-%d"))
#Define our connection string
conn_string = "host='REMOVED' dbname='REMOVED' user='REMOVED' password='REMOVED' connect_timeout=3"
# print the connection string we will use to connect
#print bcolors.MAGENTA + 'Connecting to database\n ->%s' % (conn_string) + bcolors.ENDC + "\n"
# get a connection, if a connect cannot be made an exception will be raised here
conn = psycopg2.connect(conn_string)
# conn.cursor will return a cursor object, you can use this cursor to perform queries
sql = conn.cursor()
print bcolors.YELLOW + "Inserting Solaris information into table.\n" + bcolors.ENDC
with open('/home/cstanley/scripts/vip/sun_ip') as ip:
hosts = ip.read().splitlines()
threads = []
for h in hosts:
t = threading.Thread(target=workon, args=(h,sql,))
t.start()
threads.append(t)
for t in threads:
t.join()
conn.commit()
sql.close()
conn.close()
if __name__ == "__main__":
main()
Пытаясь выяснить, что здесь происходит. Почему он работает, когда я ввожу UX10
, но не когда я ввожу sdsdsdsdsdsd
? Я даже попытался заменить его solaris-cdc
так же, как в первой части запроса, но это также не удается. Что происходит в мире!?
Как «UX10» нормальный, а «sdsdsdsdsd» - нет? Кроме того, как работает «solaris-cdc» на одном поле, а другое поле «solaris-cdc» не работает? Оба поля являются одинаковыми. Очевидно, что это проблема, но каково решение? Мне кажется, что потоки каким-то образом ставят двоичные данные там, где это не должно. Вы видите, что выполнение двух EXACT-запросов вызывает разные проблемы, когда поле является «UX10» и «sdsdsdsdsd». Проблема очевидна, да postgres ожидает UTF-8 и получает что-то еще.Это не мой вопрос - мой вопрос в том, почему мой скрипт отправляет двоичный файл. –
Я набрал sdsdsdsdsd вручную - и при смене его на 'UX10' он работает. Таким образом, из этого вышло из resultHOST [0], я бы ожидал, что он все равно выдает ошибку, когда поле было изменено на 'UX10' –
Можете ли вы получить MVCE этого? На вопрос, конечно, нет минимального, полного и проверяемого примера - далеко от него –