Importar 3.900.000 registros

Importar 3.900.000 registros

Postby FiveWiDi » Wed Jul 03, 2013 6:31 pm

Hola a todos,

Debo importar a DBF (por comodidad), 3.900.000 registros.
La información la tendré en un TXT de 3.900.000 líneas; cada lína tiene 4 campos separados por ";".

Son campos cuyo contenido son cifras y por tanto los puedo trabajar como números o cadenas.

Creen que debo tener algo especial en cuenta?
Ustedes como lo harían?

Gracias.
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1083
Joined: Mon Oct 10, 2005 2:38 pm

Re: Importar 3.900.000 registros

Postby karinha » Wed Jul 03, 2013 7:00 pm

João Santos - São Paulo - Brasil - Phone: +55(11)95150-7341
User avatar
karinha
 
Posts: 7339
Joined: Tue Dec 20, 2005 7:36 pm
Location: São Paulo - Brasil

Re: Importar 3.900.000 registros

Postby Marcelo Via Giglio » Wed Jul 03, 2013 11:38 pm

Hola,

se me ocurre algo así

Code: Select all  Expand view


      cImport := MEMOREAD("inputFile.txt")
     
      aRows := HB_ATokens( cImport, CHR(13) )

      FOR i := 1 TO Len( aRows )
            aFields :=  HB_ATokens( aRows[i], ";" )
            ............
            AADD( aData, aFields )
      NEXT
 


Te queda en aData toda la importación para que hagas el tratamiento que necesites antes de subirlo al DBF, o si ves mejor lo pasas directamente al DBF

saludos

Marcelo
Marcelo Via Giglio
 
Posts: 1051
Joined: Fri Oct 07, 2005 3:33 pm
Location: Cochabamba - Bolivia

Re: Importar 3.900.000 registros

Postby surGom » Thu Jul 04, 2013 9:55 am

Hola hace cuatro de años tuve un problema similar, ya que rentas (tanto provincial como de capital), generaba un archivo txt para que nosotros tuvieramos las alícuotas para aplicar a los contribuyentes. El problema era que tenía una amplitud de entre 89 megas y 30 respectivamente.

Al intentar hacerlo era practicamente imposible y se me quedaba como colgado (hice varias pruebas y todas con el mismo resultado). La solución me la dió Carlos Vargas utilizando Visual Fox, que lo lee sin problemas. Uso el programa externamente e importo el resultado a Dbf
Te envío una de las formas que lo hacía en cliper hasta mas o menos 4 megas funcionaba bien

Code: Select all  Expand view
#include "Fivewin.ch"



FUNCTION PADCAPITAL()

LOCAL MfILE := cGetfile32("Archivo (*.txt) | *.txt |","Seleccione padron a importar")
local cCuit
local nPer
local nRet
local cRazon
local cStrline
local nTotal
local oMtr
local cAlias


//ShellExecute( ,"open",mfile,,,1 )

if !pasaje1("padroncf");return nil;endif
set order to 1
dbzap()



oTxtFil := TTxtFile():New( mfile )
nTotal := oTxtFil:RecCount()
DEFINE DIALOG odlg resource "dia_indexo"
odlg:cCaption := "Generando padron capital"

REDEFINE PROGRESS oMtr  id 160 of odlg

REDEFINE SAY oSay var "texto bajado de internet" id 125


ACTIVATE DIALOG odlg CENTERED NOWAIT ON INIT ( oMtr:SetRange( 1, ntotal ),oMtr:setpos(0))




FOR z := 1 TO oTxtFil:RecCount()
    cStrline := oTxtFil:ReadLine()
 
    cCuit := substr(cStrline,28,11)
    nPer :=  val(substr(cStrline,46,4))
    nRet := val(substr(cStrline,51,4))
    cRazon := substr(cStrline,62,60)

    if yabase()
       replace cuit with cCuit, percepcion with nPer, retencion with nret, razon with cRazon
       dbcommit()
       dbunlock()
    endif
    oTxtfil:skip()
    oMtr:nPosition +=1
next

oTxtFil:close()

delete tag capcuit
index on cuit tag capcuit

odlg:end()
dbcloseall()
 


El código que uso actualmente para estos casos es

Code: Select all  Expand view
#include "FIVEWIN.CH"

FUNCTION buscotxto(lcapital)


local cinit := GetWinDir()+"\mega.ini"
local dgr := GetpvProfString("camino","renpath",,cinit)
local dgrc :=  GetpvProfString("camino","rencpath",,cinit)
local programa := GetpvProfString("camino","curproga",,cinit)
local memo:=GetpvProfString("camino","curpath",,cinit) +"\" +  iif(!lcapital, "padron.dbf","padroncf.dbf")
local memo1:=  GetpvProfString("
camino","curpath",,cinit) +"\" + iif(!lcapital, "padron.cdx","padroncf.cdx")


if !lcapital
  waitrun(dgr + "
import")                 // (1)
else
  waitrun(dgrc + "
importo")              // (2)
endif


sysrefresh()

waiton()



if file(memo)  

 erase &memo
 erase &memo1
endif

if !lcapital
     use padron
     copy to &memo
     dbclosearea()
     erase padron.dbf
     if !pasaje1("
padron");return nil ;endif
     delete tag cuit
     index on field4 tag cuit
     cierroalias(alias())
else
     use padroncf
     copy to &memo
     dbclosearea()
     erase padroncf.dbf
     if !pasaje1("
padroncf");return nil ;endif
     delete tag cuit
     index on field4 tag cuit
     cierroalias(alias())
endif

waitoff()



if msgyesno("
Desea Actualizar las bases de datos" + CRLF + "Clientes y proveedores","Mensaje del sistema")
    if !lcapital
      actualcli(.t.)
      actualcli(.f.)
        else
      actucap(.t.)
      actucap(.f.)
        endif
endif

return nil


/******************************************************************************/
function actualcli(lcliente)
local  oRen
local oMae
local oProve
local aObj := array(0)
local cTexto:= "
Actualizando alícuotas rentas de clientes"
local ntotal := 0



if !pasaje("
padron");return nil ;endif
database oRen
aadd(aObj,oRen)
oRen:setorder(1)

if lcliente
    if !pasaje("
maeclie");cldata(aObj) ;return nil ;endif
    database oMae
    aadd(aObj,oMae)
    oMae:setorder(3)
    ntotal := oMae:RecCount()
    oMae:beof := {|| nil}
    oMae:gotop()


    MUESTRO(oMae, oRen,ntotal,ctexto,.t.)
else

    if !pasaje("
maepro");cldata(aObj) ;return nil ;endif
    database oProve
    aadd(aObj,oProve)
    oProve:setorder(3)
    oProve:beof := {|| nil}
    oProve:gotop()


    cTexto:= "
Actualizando alícuotas rentas de proveedores"

    MUESTRO(oProve, oRen,ntotal,ctexto,.f.)
endif
cldata(aObj)

return nil
/******************************************************************************/

STATIC FUNCTION MUESTRO(oDbf,oRen,nTotal,ctexto, lcliente)

local odlg
local oMtr
local oSay
local nRetiene := "
"
local nPercibe := "
"
local cCuit := "
"

DEFINE DIALOG odlg resource "
dia_indexo"
odlg:cCaption := cTexto

REDEFINE PROGRESS oMtr  id 160 of odlg


REDEFINE SAY oSay var ctexto id 125


ACTIVATE DIALOG odlg CENTERED NOWAIT ON INIT ( oMtr:SetRange( 1, ntotal ),oMtr:setpos(0))

odbf:gotop()
do
     oMtr:nPosition +=1  
      cCuit :=  STRTRAN(oDbf:cuit, "
-", "")
      oRen:seek(cCuit)
        if oRen:found()  
         if reviso(oDbf)
            nPercibe :=  strtran(oRen:field8,"
,",".")
            nRetiene := strtran(oRen:field9,"
,",".")
            oDbf:percibe := val( nPercibe )
            oDbf:retiene :=  val( nRetiene)
            oDbf:save()          
            oDbf:commit()
            oDbf:unlock()
                endif
       elseif lcliente .and. oDbf:nropcia = 1
        oDbf:percibe :=  3
        oDbf:retiene :=  1.75   
        oDbf:save()          
        oDbf:commit()
        oDbf:unlock()
      endif
      oDbf:skip()
      sysrefresh()
until oDbf:eof()

odlg:end()
return nil
/******************************************************************************/
function actucap(lcliente)                           //actualizacion alicuotas de capital
local  oRen
local oMae
local oProve
local aObj := array(0)
local cTexto:= "
Alícuotas rentas capital de clientes"
local ntotal := 0



if !pasaje("
padroncf");return nil ;endif
database oRen
aadd(aObj,oRen)
oRen:setorder(1)

if lcliente
    if !pasaje("
maeclie");cldata(aObj) ;return nil ;endif
    database oMae
    aadd(aObj,oMae)
    oMae:setorder(3)
    ntotal := oMae:RecCount()
    oMae:beof := {|| nil}
    waiton()
    do  
      if reviso(oMae)
         oMae:percap := 0
         oMae:retcap := 0
         oMae:save()
         oMae:commit()
         oMae:unlock()
          endif  
      oMae:skip()
      sysrefresh()
    until oMae:eof()
    waitoff()

    MUESTRO1(oMae, oRen,ntotal,ctexto,.t.)
else

    if !pasaje("
maepro");cldata(aObj) ;return nil ;endif
    database oProve
    aadd(aObj,oProve)
    oProve:setorder(3)
    oProve:beof := {|| nil}
    oProve:gotop()
    waiton()
    do  
      if reviso(oProve)
         oProve:percap := 0
         oProve:retcap := 0
         oProve:save()
         oProve:commit()
         oProve:unlock()
          endif  
      oProve:skip()
      sysrefresh()
    until oProve:eof()
    waitoff()
    ntotal := oProve:RecCount()
    oProve:beof := {|| nil}
    cTexto:= "
Alícuotas rentas capital de proveedores"

    MUESTRO1(oProve, oRen,ntotal,ctexto,.f.)
endif
cldata(aObj)

return nil

/******************************************************************************/
STATIC FUNCTION MUESTRO1(oDbf,oRen,nTotal,ctexto, lcliente)

local odlg
local oMtr
local oSay
local nRetiene := "
"
local nPercibe := "
"
local cCuit := "
"

DEFINE DIALOG odlg resource "
dia_indexo"
odlg:cCaption := cTexto

REDEFINE PROGRESS oMtr  id 160 of odlg


REDEFINE SAY oSay var ctexto id 125


ACTIVATE DIALOG odlg CENTERED NOWAIT ON INIT ( oMtr:SetRange( 1, ntotal ),oMtr:setpos(0))

odbf:gotop()
do
     oMtr:nPosition +=1  
      cCuit :=  STRTRAN(oDbf:cuit, "
-", "")
      oRen:seek(cCuit)
        if oRen:found()  
         if reviso(oDbf)
            nPercibe := strtran(oRen:field8,"
,",".")
            nRetiene := strtran(oRen:field9,"
,",".")
            oDbf:percap := val( nPercibe )
            oDbf:retcap :=  val( nRetiene)
            oDbf:save()          
            oDbf:commit()
            oDbf:unlock()
                endif
      endif
      oDbf:skip()
      sysrefresh()
until oDbf:eof()

odlg:end()
return nil
/******************************************************************************/


dónde import.exe e importo.exe (1) y (2) respectivamente me generan una dbf (creada desde VIsual fox) que luego importo a mis bases de datos... Y lo hace de forma muy rápida.

Luis
surGom
 
Posts: 639
Joined: Wed Oct 19, 2005 12:03 pm

Re: Importar 3.900.000 registros

Postby Antonio Linares » Thu Jul 04, 2013 10:13 am

Carlos,

Pienso que la clave para que el proceso vaya rápido es usar una forma eficiente de leer el fichero.

Si cada línea tiene la misma longitud entonces puedes hacer un código a medida que recorra el fichero muy rapido, evitando usar arrays, pues solo duplicarian la información en memoria.

Si la longitud de cada registro se mantiene, no hay que usar At(), sino leer una cantidad x de bytes cada vez
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41390
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Importar 3.900.000 registros

Postby acuellar » Thu Jul 04, 2013 12:28 pm

Si el contenido no tiene comas "," reemplazar todos los ";" por ","
Usar APPEND
Code: Select all  Expand view

USE BASE NEW EXCLUSIVE //CON LOS 4 CAMPOS
DBZAP()
APPEND FROM ARCHIVO.TXT DELIMITED
 


Seria bueno mostrar un poco del contenido del archivo de texto

Saludos,

Adhemar
Saludos,

Adhemar C.
User avatar
acuellar
 
Posts: 1594
Joined: Tue Oct 28, 2008 6:26 pm
Location: Santa Cruz-Bolivia

Re: Importar 3.900.000 registros

Postby FiveWiDi » Sat Jul 06, 2013 6:36 pm

Muchas gracias a todos por las ideas.
De momento no las puedo aplicar; el equipo que me tiene que proporcionar el fichero esta teniendo problemas para generarlo (sin comentarios).
Un Saludo
Carlos G.

FiveWin 24.02 + Harbour 3.2.0dev (r2403071241), BCC 7.7 Windows 10
FiveWiDi
 
Posts: 1083
Joined: Mon Oct 10, 2005 2:38 pm

Re: Importar 3.900.000 registros

Postby Antonio Linares » Sun Jul 07, 2013 1:01 pm

Carlos,

muy bueno :-D
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 41390
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: cmsoft and 71 guests