Найти - Пользователи
Полная версия: кодировка python + Excel + FB
Начало » Python для новичков » кодировка python + Excel + FB
1
Ace
Добрый !

Инструменты: 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 для записи в БД ?
PanovSergey
В чем вопрос?
`
Ace
Виноват. Сам вопрос - как выковырять из Sheet.Cells(y,2) строку в кодировке Windows 1251 для записи в БД ?
pyuser
Если память мне не изменяет, то как-то так:
Sheet.Cells.Item(row, col).Value
Ace
Пардон, вопрос был про кодировку. Допускаю, что задал его коряво. Вот с чего началось

Следующий код фуночки
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
pyuser
Если память мне не изменяет, то как-то так:
я с ВБ и ВБС работал и работаю, вопрос как эти данные прокрутить через питон
Ace
Забавно. Такая же ошибка при инсерте чисто латинской строки

Уважаемый модератор, перенесите пожалуйста топик в раздел СУБД
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