Найти - Пользователи
Полная версия: threading и кодировка
Начало » Python для новичков » threading и кодировка
1 2
sonniy
заметил одну забавную вещь:
код запущенный в цикле , один через threading, второй просто
код собственно принимает инфу и кладет ее в БД оракл при помощи cx_Oracle

забавность :
запущенный в threading кладет нормально, а без threading кладет квадратики вместо русских символов

от чего такая разница ?
Piton23
Мне кажется кодировка не зависит никак от поточности. Проверьте кодировку файлов (если у вас код с потоками и без разделен на разные файлы), если ж все в одном скрипте то выложите код. Я надеюсь что в базе у вас кодировка соответствующая.
sonniy
Кодировка в БД соответствующая
некоторые функции я убрал, но сути дела они не меняют
работает нормально :
# -*- coding: utf-8 -*-
import socket, string
import xml.dom.minidom
import datetime
import threading
import cx_Oracle
###
# Импорт среды джанго
# Этот файл должен лежать в проекте джанго
###
import os,sys,codecs
sys.path.append(os.path.join(os.path.abspath('..'), 'www'))
from django.core.management import setup_environ
import settings
setup_environ(settings)

from taxi.myapp.models import cancels
###
#
###
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)

class Thread_from(threading.Thread):
def run(self):
import xml.dom.minidom
package_type = xml_type(result)
xml_from = xml.dom.minidom.parseString(result)
if package_type==u'5':
xml = '<b>bla bla bla<b>'
sock.send(xml)
print "[%s] Отправлено:" % datetime.datetime.now(),xml
elif package_type==u'15':
try:
b = cancels(
comments = getText(xml_from.getElementsByTagName("Comment")[0].childNodes),
)
b.save(using='oracle')
except IndexError:
print "[%s] В заказе отсутствуют теги" % datetime.datetime.now()


HOST = 'host'
PORT = port

try :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
except Exception, e:
print e

while True:
len_recv = 1
result = sock.recv(len_recv)
len_recv = get_len_xml(result)
result = get_xml(len_recv)
print "[%s] Получено:" % datetime.datetime.now(),result
print "Длина полученой XML =",len(result)
Thread_from().start()
так как я привык работать с django , я использовал ее orm для работы

и все таки суть в том что если сделать так :
# -*- coding: utf-8 -*-
import socket, string
import xml.dom.minidom
import datetime
import threading
import cx_Oracle
###
# Импорт среды джанго
# Этот файл должен лежать в проекте джанго
###
import os,sys,codecs
sys.path.append(os.path.join(os.path.abspath('..'), 'www'))
from django.core.management import setup_environ
import settings
setup_environ(settings)

from taxi.myapp.models import cancels
###
#
###
def getText(nodelist):
rc = []
for node in nodelist:
if node.nodeType == node.TEXT_NODE:
rc.append(node.data)
return ''.join(rc)

HOST = 'host'
PORT = port

try :
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((HOST, PORT))
except Exception, e:
print e

while True:
len_recv = 1
result = sock.recv(len_recv)
len_recv = get_len_xml(result)
result = get_xml(len_recv)
print "[%s] Получено:" % datetime.datetime.now(),result
print "Длина полученой XML =",len(result)
import xml.dom.minidom
package_type = xml_type(result)
xml_from = xml.dom.minidom.parseString(result)
if package_type==u'5':
xml = '<b>bla bla bla<b>'
sock.send(xml)
print "[%s] Отправлено:" % datetime.datetime.now(),xml
elif package_type==u'15':
try:
b = cancels(
comments = getText(xml_from.getElementsByTagName("Comment")[0].childNodes),
)
b.save(using='oracle')
except IndexError:
print "[%s] В заказе отсутствуют теги" % datetime.datetime.now()
то есть перенести блок кода непосредственно в цикл , то все начинает ложится квадратами
так тоже не работает, все те же квадраты
comments = getText(xml_from.getElementsByTagName("Comment")[0].childNodes).encode('utf8')
sonniy
провел несколько экспериментов и выяснил что квадраты оно кладет в uft8

так проходит и в поле остаются квадраты:
# -*- coding: utf-8 -*-
import cx_Oracle
...
...

connstr = login+'/'+passwd+'@'+ip+':'+port_ora+'/'+bd
conn = cx_Oracle.connect(connstr)
cursor = conn.cursor()

cursor.execute("update cancels set type='Отмена' where id=5788")
conn.commit()
так тоже самое :
cursor.execute("update cancels set type='%s' where id=5788" % u'Отмена'.encode('utf8'))
conn.commit()
а вот так выдает ошибку:
cursor.execute("update cancels set type='%s' where id=5788" % u'Отмена'))
conn.commit()

UnicodeEncodeError: 'ascii' codec can't encode characters in position 25-30: ordinal not in range(128)
Piton23
Раз у тебя квадратики то это либо первые управляющие символы (типа 0x01 == SOH, 0x04 == EOT) которые иногда отображаются как квадратики. Либо это русские буквы.

Я даже не смотрел код, т.к. не силен в Оракле. Ты попробуй накидать 2 разных файла (обычное занесение данных, и во втором через потоки), так в 10-15 строк кода. А то что ты логику вставил это врятли кому то интересно (и будет читать). Как будет готово скинь 2 кода (был бы оракл под рукой я мб и протестировал :) ). Кстати сам когда упростишь увидишь мб свою ошибку. Есть утилитки позволяющие просматривать в 16 формате, одна из таких WinHex, там можно явно хоть посмотреть что за квадратики там (т.е. какой там код) и оттуда уже копать, но я так думаю что либо кодировки не совпадают, либо в определенных местах не делаются преобразования encode/decode. Кстати в базе данных точно кодировка utf?
sonniy
рылся в доках и наткнулся на такую штуку:
>>> conn.encoding
'US-ASCII'
хотя в БД NLS_CHARACTERSET = AL32UTF8
sonniy
Piton23
Раз у тебя квадратики то это либо первые управляющие символы (типа 0x01 == SOH, 0x04 == EOT) которые иногда отображаются как квадратики. Либо это русские буквы.

Я даже не смотрел код, т.к. не силен в Оракле. Ты попробуй накидать 2 разных файла (обычное занесение данных, и во втором через потоки), так в 10-15 строк кода. А то что ты логику вставил это врятли кому то интересно (и будет читать). Как будет готово скинь 2 кода (был бы оракл под рукой я мб и протестировал :) ). Кстати сам когда упростишь увидишь мб свою ошибку. Есть утилитки позволяющие просматривать в 16 формате, одна из таких WinHex, там можно явно хоть посмотреть что за квадратики там (т.е. какой там код) и оттуда уже копать, но я так думаю что либо кодировки не совпадают, либо в определенных местах не делаются преобразования encode/decode. Кстати в базе данных точно кодировка utf?
я оставил только, то что ты как раз просишь, то что работает с БД… весь остальной бред точно никому не нужен :)

на сколько я понял дело не в потоках, так как я изменил немного скрипт в сторону оптимизации ресурсов:
- сам цикл переместил в поток
- добавил очереди (from Queue import Queue)

запускаю два потока один помещает в очереди, другой работает с этой очередью … и все равно кладет свои гребаные квадратики :)
а вот если тоже самое сделать не на ходу, а как бы одноразовое использование, то все положило нормально (при использование ORM Django)
Piton23
А ты прочитай из базы эти квадратики, потом через NotePad++ поиграйся с кодировками, мб там что нить проясниться.

Просто если проблема не с кодировками а дело обстоит с особенностями оракла, то от меня мало будет толку :) . Хотя я все ж думаю что косяк с кодировками. Проверь все как собирался питон сам, и другое, если везде кодировки одни и теже, то извлеките эти квадратики в файл, а там уже смотрите.
sonniy
назад считываются знаки вопроса, и в любой кодировке это знаки вопроса
sonniy
>>> conn.encoding
'US-ASCII'
этот параметр показывает в какой кодировке оракл принимает от меня информацию
но я так и не понял как его можно поменять, сама функция encoding в cx_Oracle ридонли
Connection.encoding
This read-only attribute returns the IANA character set name of the character set in use by the Oracle client.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB