Уведомления

Группа в Telegram: @pythonsu

#1 Май 6, 2015 12:12:24

Psayker09
Зарегистрирован: 2015-05-06
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсирование файла

Помогите разбить файл типа:

Абрамова,Валентина,Александровна,27/11/1949,50041088828891,Заключение брака,отдел ЗАГС
АКИМОВ,СЕРГЕЙ,ВАСИЛЬЕВИЧ,30/11/1983,50041088828063,Заключение брака,отдел ЗАГС
АКИМОВ,СЕРГЕЙ,ВАСИЛЬЕВИЧ,30/11/1983,50041088828063,Расторжение брака,отдел ЗАГС
АЛЕШКОВА,ОЛЬГА,СЕРГЕЕВНА,22/12/1975,50041088829728,Заключение брака,отдел ЗАГС
АЛЕШКОВА,ОЛЬГА,СЕРГЕЕВНА,22/12/1975,50041088829728,Заключение брака,отдел ЗАГС
АЛЕШКОВА,ОЛЬГА,СЕРГЕЕВНА,22/12/1975,50041088829728,Расторжение брака,отдел ЗАГС
Батышкина,Ольга,Владимировна,03/04/1987,50041088830114,Заключение брака,отдел ЗАГС
Безрукова,Ольга,Николаевна,03/04/1983,50041088824428,Заключение брака,отдел ЗАГС
Евенко,Алексей,Сергеевич,07/05/1985,50041088822689,Смерть,Специализированный отдел регистрации актов гражданского состояния о смерти
Таким образом:
Фамилия Имя Отчество Дата_рождения(в формате дд.мм.ггг) ID Информация
И вставить эти данные в базу

Офлайн

#2 Май 6, 2015 12:24:53

sander
Зарегистрирован: 2015-02-19
Сообщения: 317
Репутация: +  53  -
Профиль   Отправить e-mail  

Парсирование файла

Psayker09

import csv

Офлайн

#3 Май 6, 2015 12:27:44

Psayker09
Зарегистрирован: 2015-05-06
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсирование файла

sander
подробнее можно?

Офлайн

#4 Май 6, 2015 12:40:51

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Парсирование файла

Офлайн

#5 Май 6, 2015 13:02:29

Psayker09
Зарегистрирован: 2015-05-06
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсирование файла

py.user.next
что-то ни чего не понятно в этом методе

Офлайн

#6 Май 6, 2015 19:59:26

hacker123
Зарегистрирован: 2015-05-06
Сообщения: 2
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсирование файла

Psayker09
Файл разбил, с базами еще не работал

import re
lines=[]
f=open(r"C:\Users\user\Desktop\123.txt","r")
for line in f.readlines():
	lines.append(line)
regul=[]
for i in range(len(lines)):
	proj=re.findall(r"\w*[ ]?[/]?\w*[^,]*[^\n]",lines[i])
	proj=list(filter(None, proj))
	regul.append(proj)
print(regul)

Офлайн

#7 Май 6, 2015 22:46:27

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Парсирование файла

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

import datetime
def prc(lin):
    spl = lin.split(",")
    f,i,o,date,ID = spl[:5]
    date = datetime.datetime.strptime(spl[3],"%d/%m/%Y")
    info = ",".join(spl[5:])
    print f,i,o,date,ID,info
    # push to db ....
map(prc,open(r"C:\Users\user\Desktop\123.txt","r").readlines())

для импорта желательно делать bulk import
http://stackoverflow.com/questions/2092757/python-and-sqlite-insert-into-table
rows = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
      ('2006-04-05', 'BUY', 'MSOFT', 1000, 72.00),
      ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
     ]:
    c.executemany('insert into stocks values (?,?,?,?,?)', rows )
    connection.commit()
(в sqlite нет времени поэтому так :( )



Офлайн

#8 Май 7, 2015 00:43:57

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10016
Репутация: +  857  -
Профиль   Отправить e-mail  

Парсирование файла

Если это csv, то запятые могут появляться и в строках, заключённых в кавычки. Поэтому простой сплит по запятым может привести к ошибке.



Офлайн

#9 Май 8, 2015 12:11:26

Psayker09
Зарегистрирован: 2015-05-06
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсирование файла

#-*- encoding cp1251 -*-
import odbc
import os
import datetime
import rarfile
import ftplib
import dbi
import info
import functions
k=0
file_folder=os.getcwd()+os.sep+'zags'+os.sep+'in'
print('получаем ответы')
functions.get_response_zags(file_folder)
date_now=(datetime.datetime.now()).strftime("%d.%m.%Y")
#создаем список необработанных файлов возвращает список полных путей к файлу
def files_find():
    list_of_files=os.listdir(file_folder)
    f_list=[]
    for file in list_of_files:
        if file.startswith('f'):
            f_list+=(file_folder+os.sep+file),
    print(f_list)
    return(f_list)
#чистка от пробелов и спецсимволов        
def dict_clean(dict_):
    for key in dict_:
        dict_[key]=dict_[key].strip() if dict_[key]!=None else ''
    return(dict_)
#
keys=['SURNAME','NAME','PATRONIMYC','DBTR_BORN','QueryKey','Text','Req_Date','Filename','seq_doc']
#Читаем ini настройки
obmen_ini_dict=functions.read_ini('obmen.ini','OBMEN')
server_ip=obmen_ini_dict['server_ip']
database=obmen_ini_dict['database']
conn_str=conn_str=functions.conn_str_create()
#print(conn_str)
#
##Считываем файлы
def file_read(dict_):
    text=str()
    filename=dict_['Filename']
    for line in open(file_folder+os.sep+filename):
        text+=line
    #print(text)    
    return(text)
##
def file_pars(file_folder):
    k=0
    name1=''
    st=''
    stop_list=['1','2','3','4','5']
    keys=['1','2','3','4','5','6','7','8', '9','10']
    blanc_dict=dict.fromkeys(['SURNAME','NAME','PATRONIMYC','DBTR_BORN','QueryKey','Text','Req_Date','Filename','seq_doc'])
    ret_dict_list=[] 
    #file=os.getcwd()+os.sep+'f2.txt'
    for file in os.listdir(file_folder):
        if file.startswith('f'):
            name1=file
            print(name1)
            for line in open(file_folder+os.sep+name1):
                k+=1
                dict_=dict(zip((keys),(line.split(','))))
                blanc_dict['SURNAME']=dict_['1']
                blanc_dict['NAME']=dict_['2']
                blanc_dict['PATRONIMYC']=dict_['3']
                blanc_dict['Filename']=file
                blanc_dict['DBTR_BORN']=dict_['4']
                blanc_dict['QueryKey']=dict_['5']
                blanc_dict['Req_Date']=(datetime.datetime.now()).strftime('%d.%m.%Y')
                blanc_dict['seq_doc']=k
                #Чистим от ненужных символов
                for key in dict_:
                    if key not in stop_list:
                        st+=dict_[key]+', '
                        #print(st)
                blanc_dict['Text']=st
                print(line)
                ret_dict_list+=blanc_dict,
    return(ret_dict_list)
#Презервируем номера для insert
def max_pack_start_seq(count_rec):
    import odbc
    seq_doc=[]
    db=odbc.odbc(conn_str)
    cursor=db.cursor()
    #скрипт для получения номера крайнего пакета для савокупности (AGENT_CODE, AGENT_DEPT_CODE, AGENT_AGREEMENT_CODE)
    max_pack_num="select max(PACK_NUMBER) from ext_input_header where agent_code = 'ЗАГС' and agent_agreement_code='ЗАГС_СОГЛ' and agent_dept_code='ЗАГС_ПОДР'"
    print('резервируем номера для новых документов')
    cursor.execute('select gen_id(seq_document,1) FROM RDB$DATABASE')
    seq_doc_start=cursor.fetchall()
    seq_doc_start=seq_doc_start[0][0]
    cursor.execute('select gen_id(seq_document,'+str(int(count_rec))+') FROM RDB$DATABASE')
    seq_doc_end=cursor.fetchall()
    seq_doc_end=seq_doc_end[0][0]
    print('зарезервированы номера с',seq_doc_start,'по',seq_doc_end)
##    
    print('задаем номер пакета уникальный для савокупности (AGENT_CODE, AGENT_DEPT_CODE, AGENT_AGREEMENT_CODE)')
    cursor.execute(max_pack_num)
    res=cursor.fetchall()
    #важно если пакетов нет, создаем первый
    max_=(1 if res[0][0]==None else res[0][0]+1)
    db.close()
    print('номер пакета', max_)
    return_dict=dict(zip(("pack_num","start_seq"),(max_,seq_doc_start)))
    return(return_dict)
#составляем строчку с из бланка для inserta
def insert_do(files_list):
    n=0
    insert_list=[]
    #бланк для заполнения
    #mp_sq_dict=max_pack_start_seq(len(xml_files_list))
    mp_sq_dict=max_pack_start_seq(len(files_list))
    bl_insert_input_header_scr="INSERT INTO EXT_INPUT_HEADER (ID, PACK_NUMBER, PROCEED, AGENT_CODE, AGENT_DEPT_CODE, AGENT_AGREEMENT_CODE, EXTERNAL_KEY, METAOBJECTNAME, DATE_IMPORT)\
VALUES ({2}, {1}, 0, 'ЗАГС', 'ЗАГС_ПОДР', 'ЗАГС_СОГЛ', {0[QueryKey]}, 'EXT_RESPONSE', '{0[Req_Date]}');"
    bl_resp="INSERT INTO EXT_RESPONSE (ID, RESPONSE_DATE, ENTITY_NAME, ENTITY_BIRTHYEAR, ENTITY_BIRTHDATE,ENTITY_INN, ID_NUM, IP_NUM, REQUEST_NUM, REQUEST_ID, DATA_STR,ANSWER_TYPE)\
VALUES ({1}, '{0[Req_Date]}', 'Загс', NULL, NULL, NULL, NULL, NULL, '{0[QueryKey]}', {0[QueryKey]}, '{0[Text]}','02');"
    for line in files_list:
        seq_num=int(mp_sq_dict['start_seq']+line['seq_doc'])
        n+=1
        insert_inp_head=bl_insert_input_header_scr.format(line,mp_sq_dict['pack_num'],seq_num)
        insert_request=bl_resp.format(line,seq_num)
        #Лист вставки
        insert_list+={'insert_header':insert_inp_head,'insert_request':insert_request},
    return(insert_list)
##загрузка непосредственно в базу    
def insert_db(list_ins):
    import odbc
    count=0
    sc=0
    db=odbc.odbc(conn_str)
    cursor=db.cursor()
    for line in list_ins:
        sc+=1
        try:
            cursor.execute(line['insert_header'])
            cursor.execute(line['insert_request'])
        except Exception as err:
            print(err)
        if sc==100:
            count+=sc
            sc=0
            print('[',count,'/',len(list_ins),']')
    count=count+sc
    print('добавленно ',count,' ответов')
##добавить переименование прочтенных файлов
def main():
    for filename in files_find():
        print(filename)
        file_dir,file_name=os.path.split(filename)
        if not os.path.exists(os.path.join(file_dir,'ok_'+file_name)):
            files_list=file_pars(file_folder)
            insert_dict_list=insert_do(files_list)            
            insert_db(insert_dict_list)
            try:
                os.rename(filename,os.path.join(file_dir,'ok_'+file_name))
                print('Файл переименован')
            except Exception as exc:
                print('can''t do this: ',exc)
        else:
            os.remove(filename)
##
main()

Сделал поиск, разбор, вставку…но почему-то вставляет только последние значения
А лучше помогите разобраться как сделать встаку сразу в разборе

Отредактировано Psayker09 (Май 8, 2015 14:31:07)

Офлайн

#10 Май 8, 2015 20:29:05

doza_and
От:
Зарегистрирован: 2010-08-15
Сообщения: 4138
Репутация: +  253  -
Профиль   Отправить e-mail  

Парсирование файла

Не спешите.
Ну вот файлы читаете - листаете директории проверяете файлы..

А можно:

import fileinput,glob
for line in fileinput.input(glob.glob("f*.*")):
    process(line)
https://docs.python.org/3/library/fileinput.html
ну и т.п.

Вообще мне кажется что в данном случае лучше сделать промежуточный tsv и импортнуть его средствами субд.

В том коде что вы привели и импорт и обработка, без всяких объяснений что и зачем. Еслb хотите чтобы вам помогли, выделяйте куски и описывайте решаемые задачи и какая у вас проблема.



Отредактировано doza_and (Май 8, 2015 20:29:47)

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version