Уведомления

Группа в Telegram: @pythonsu

#1 Фев. 22, 2012 07:50:03

sonniy
От:
Зарегистрирован: 2009-12-18
Сообщения: 84
Репутация: +  0  -
Профиль   Отправить e-mail  

threading и кодировка

заметил одну забавную вещь:
код запущенный в цикле , один через threading, второй просто
код собственно принимает инфу и кладет ее в БД оракл при помощи cx_Oracle

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

от чего такая разница ?



Офлайн

#2 Фев. 22, 2012 08:32:51

Piton23
От:
Зарегистрирован: 2011-10-17
Сообщения: 139
Репутация: +  5  -
Профиль   Отправить e-mail  

threading и кодировка

Мне кажется кодировка не зависит никак от поточности. Проверьте кодировку файлов (если у вас код с потоками и без разделен на разные файлы), если ж все в одном скрипте то выложите код. Я надеюсь что в базе у вас кодировка соответствующая.

Офлайн

#3 Фев. 22, 2012 09:04:53

sonniy
От:
Зарегистрирован: 2009-12-18
Сообщения: 84
Репутация: +  0  -
Профиль   Отправить e-mail  

threading и кодировка

Кодировка в БД соответствующая
некоторые функции я убрал, но сути дела они не меняют
работает нормально :

# -*- 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')



Отредактировано (Фев. 22, 2012 09:06:45)

Офлайн

#4 Фев. 24, 2012 11:25:22

sonniy
От:
Зарегистрирован: 2009-12-18
Сообщения: 84
Репутация: +  0  -
Профиль   Отправить e-mail  

threading и кодировка

провел несколько экспериментов и выяснил что квадраты оно кладет в 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)



Офлайн

#5 Фев. 24, 2012 12:11:33

Piton23
От:
Зарегистрирован: 2011-10-17
Сообщения: 139
Репутация: +  5  -
Профиль   Отправить e-mail  

threading и кодировка

Раз у тебя квадратики то это либо первые управляющие символы (типа 0x01 == SOH, 0x04 == EOT) которые иногда отображаются как квадратики. Либо это русские буквы.

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

Офлайн

#6 Фев. 24, 2012 12:21:44

sonniy
От:
Зарегистрирован: 2009-12-18
Сообщения: 84
Репутация: +  0  -
Профиль   Отправить e-mail  

threading и кодировка

рылся в доках и наткнулся на такую штуку:

>>> conn.encoding
'US-ASCII'
хотя в БД NLS_CHARACTERSET = AL32UTF8



Офлайн

#7 Фев. 24, 2012 13:01:45

sonniy
От:
Зарегистрирован: 2009-12-18
Сообщения: 84
Репутация: +  0  -
Профиль   Отправить e-mail  

threading и кодировка

Piton23
Раз у тебя квадратики то это либо первые управляющие символы (типа 0x01 == SOH, 0x04 == EOT) которые иногда отображаются как квадратики. Либо это русские буквы.

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

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

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



Офлайн

#8 Фев. 24, 2012 13:19:48

Piton23
От:
Зарегистрирован: 2011-10-17
Сообщения: 139
Репутация: +  5  -
Профиль   Отправить e-mail  

threading и кодировка

А ты прочитай из базы эти квадратики, потом через NotePad++ поиграйся с кодировками, мб там что нить проясниться.

Просто если проблема не с кодировками а дело обстоит с особенностями оракла, то от меня мало будет толку :) . Хотя я все ж думаю что косяк с кодировками. Проверь все как собирался питон сам, и другое, если везде кодировки одни и теже, то извлеките эти квадратики в файл, а там уже смотрите.

Офлайн

#9 Фев. 24, 2012 13:24:26

sonniy
От:
Зарегистрирован: 2009-12-18
Сообщения: 84
Репутация: +  0  -
Профиль   Отправить e-mail  

threading и кодировка

назад считываются знаки вопроса, и в любой кодировке это знаки вопроса



Отредактировано (Фев. 24, 2012 13:24:59)

Офлайн

#10 Фев. 24, 2012 13:28:37

sonniy
От:
Зарегистрирован: 2009-12-18
Сообщения: 84
Репутация: +  0  -
Профиль   Отправить e-mail  

threading и кодировка

>>> 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.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version