Уведомления

Группа в Telegram: @pythonsu

#1 Март 18, 2014 10:22:42

Ace
Зарегистрирован: 2012-09-05
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

кодировка python + Excel + FB

Добрый !

Инструменты: win7 64, python 3.3.4 x86, Excel 2010, Firebird 2.5.2 x64, fdb 1.4
Задача: открыть файл Excel и записать из него данные в БД FB. Особенности - файл из офиса 2003 (7 листов по 65000 элементов, итого примерно 450 000 элементов)

код (в первом приближении, обрабатываются не все поля и столбцы для скорости отладки)

# coding: utf-8
from win32com.client import Dispatch
import pythoncom
import datetime
import sys
import fdb
#==================================================================      
def main(argv=None):
    start_time=datetime.datetime.now()
    print(start_time)
    fb_conn = fdb.connect(dsn='firebird:d:\\pgn.FDB',user='user',password='password')
    trans=fb_conn.trans()
    trans.begin
    fb_cur=trans.cursor()
    sql_prep=fb_cur.prep(r"INSERT INTO gpk_input (lat_name,name,to_date) VALUES (?,?,?)")
    
    xlApp = Dispatch("Excel.Application")
    xlApp.Visible=False
    xlWb = xlApp.Workbooks.Open(r"D:\Documents\children.xls")
    
    try:
        for Sheet in xlWb.WorkSheets:
            print("Sheet=",Sheet.Name," ",datetime.datetime.now())
            for y in range(2,10):       # Это для теста. Реально for y in range(2,65002):
                if str(Sheet.Cells(y,1)) != 'None':
                    # Sheet.Cells(y,1) - ФИО в латинской транскрипции
                    # Sheet.Cells(y,2) - ФИО на русском
                    # Sheet.Cells(y,3) - дата чего-то . Пока не интересно
                    # переделка даты - сейчас не в этом вопрос
                    dt1=str(Sheet.Cells(y,3))
                    dt1=dt1[0:19]
                    dt1=str(dt1[8:10])+'.'+str(dt1[5:7])+'.'+str(dt1[0:4])+' '+str(dt1[11:])
                    
                    print(type(Sheet.Cells(y,2)))   # = <class 'win32com.client.CDispatch'>
                    rus_name=str(Sheet.Cells(y,2))
                    print(type(rus_name))             # = <class 'str'>
                    print('-------\n','orig=',rus_name)   # в cmd выводит нормально, вижу кирилицу
                    fb_cur.execute(sql_prep,[Sheet.Cells(y,1),rus_name,dt1]) # ошибка 'utf-8' codec can't decode ... : invalid continuation byte
        trans.commit()
        fb_cur.close()        
        trans.close()
    except Exception as e3:
        print("main try:","Line "+format(sys.exc_info()[-1].tb_lineno),e3.__str__())
        print("Sheet='",Sheet.Name,"' y=",y)        
        trans.rollback()
        fb_cur.close()
        trans.close()
        
    xlApp.Quit()        
    fin_time=datetime.datetime.now()
    print(fin_time," | ",fin_time-start_time)
#==========================================        
if __name__ == "__main__":
    main()

Я так понял, print автоматом (что нетипично для питона) конвертирует строку для вывода на экран.
Вариант rus_name.decode('unicode_escape').encode('cp1251') не помог

Виноват. Сам вопрос - как выковырять из Sheet.Cells(y,2) строку в кодировке Windows 1251 для записи в БД ?

Отредактировано Ace (Март 18, 2014 16:19:49)

Офлайн

#2 Март 18, 2014 15:00:31

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

кодировка python + Excel + FB

Офлайн

#3 Март 18, 2014 16:30:45

Ace
Зарегистрирован: 2012-09-05
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

кодировка python + Excel + FB

Виноват. Сам вопрос - как выковырять из Sheet.Cells(y,2) строку в кодировке Windows 1251 для записи в БД ?

Офлайн

#4 Март 19, 2014 01:40:59

pyuser
От:
Зарегистрирован: 2007-05-13
Сообщения: 658
Репутация: +  36  -
Профиль   Отправить e-mail  

кодировка python + Excel + FB

Если память мне не изменяет, то как-то так:

Sheet.Cells.Item(row, col).Value



Офлайн

#5 Март 19, 2014 08:41:54

Ace
Зарегистрирован: 2012-09-05
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

кодировка python + Excel + FB

Пардон, вопрос был про кодировку. Допускаю, что задал его коряво. Вот с чего началось

Следующий код фуночки

def main(argv=None):
    start_time=datetime.datetime.now()
    print(start_time)
    fb_conn = fdb.connect(dsn='firebird:d:\\pgn.FDB',user='user',password='password')
    trans=fb_conn.trans()
    trans.begin
    fb_cur=trans.cursor()
    sql_prep=fb_cur.prep(r"INSERT INTO gpk_input (lat_name,name,to_date) VALUES (?,?,?)")
    
    xlApp = Dispatch("Excel.Application")
    xlApp.Visible=False
    xlWb = xlApp.Workbooks.Open(r"D:\Documents\children.xls")
    try:
        for Sheet in xlWb.WorkSheets:
            print("Sheet=",Sheet.Name," ",datetime.datetime.now())
            for y in range(2,10):
                if str(Sheet.Cells(y,1)) != 'None':
                    dt1=str(Sheet.Cells(y,3))
                    dt1=dt1[0:19]
                    dt1=str(dt1[8:10])+'.'+str(dt1[5:7])+'.'+str(dt1[0:4])+' '+str(dt1[11:])
                    print(type(Sheet.Cells(y,2)))
                    rus_name=str(Sheet.Cells(y,2))
                    print(type(rus_name))
                    print('-------\n','orig=',rus_name)
                    fb_cur.execute(sql_prep,[Sheet.Cells(y,1),rus_name.encode('utf-8'),dt1])
        trans.commit()
        fb_cur.close()        
        trans.close()
    except Exception as e3:
        print("main try:","Line "+format(sys.exc_info()[-1].tb_lineno),e3.__str__())
        print("Sheet='",Sheet.Name,"' y=",y)        
        trans.rollback()
        fb_cur.close()
        trans.close()
        
    xlApp.Quit()        
    fin_time=datetime.datetime.now()
    print(fin_time," | ",fin_time-start_time)

при выполнении из cmd.exe дает такую ошибку

('Error while executing SQL statement:\n- SQLCODE: -413\n- conversion error from string “КАСАТКИНА АЛЕНА”\n- conversion error from string “КАСАТКИНА АЛЕНА”\n- conversion error from string “КАСАТКИНА АЛЕНА”', -413, 335544334)

и при изменении запроса на явное приведение
sql_prep=fb_cur.prep(r"INSERT INTO gpk_input (lat_name,name,to_date) VALUES (?,CAST(? AS VARCHAR(50)),?)")
ошибка эта же

Ошибка вроде на стороне ФБ, но я для начала обвинил питон в его работе с кодировками.
Или сей вопрос не для “песочницы”, а для СУБДшников ?

Офтоп - как картинку вложить в пост ?

Отредактировано Ace (Март 19, 2014 08:51:37)

Офлайн

#6 Март 19, 2014 08:43:50

Ace
Зарегистрирован: 2012-09-05
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

кодировка python + Excel + FB

pyuser
Если память мне не изменяет, то как-то так:
я с ВБ и ВБС работал и работаю, вопрос как эти данные прокрутить через питон

Офлайн

#7 Март 19, 2014 09:10:09

Ace
Зарегистрирован: 2012-09-05
Сообщения: 43
Репутация: +  0  -
Профиль   Отправить e-mail  

кодировка python + Excel + FB

Забавно. Такая же ошибка при инсерте чисто латинской строки

Уважаемый модератор, перенесите пожалуйста топик в раздел СУБД

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version