tiny ‘n’ smart
database layer

Odkazy: dibi | API reference

Oznámení

Omlouváme se, provoz fóra byl ukončen

Dibi a Multi Insert – jiné možnosti než %m

před 9 lety

neologyc
Člen | 13

Dobrý den,

snažím se pomocí multi insertu vložit do DB velké množství dat (cca 30MB) a chtěl jsem pro to využít dibi a přepínač %m.
Bohužel ten vyžaduje, aby pole bylo ve formátu

<?php
$a = array (
    "key1" => array(hodnoty do sloupce s názvem "key1"),
    "key2" => array(hodnoty do sloupce s názvem "key2"),
    ...
)
?>

Moje pole je ale ve formátu:

<?php
$a = array (
    array(hodnoty pro 1. insert), //
    array(hodnoty pro 2. insert),
    ...
)
?>

Pro příklad:
Nemám

<?php
$a = array (
    "id" => array(1,2,3,4),
    "name" => array("Pepa","Lenka","Arnošt","Hugo"),
)
?>

Ale mám tuto strukturu

<?php
$a = array (
    array(1,"Pepa"),
    array(2,"Lenka"),
    array(3,"Arnošt"),
    array(4,"Hugo")
)
?>

a v dalším poli pak jména sloupců v DB.

Převod pole z toho které mám na to, které vyžaduje %m naráží na limity mého hostingu, prot bych Vás rád požádal o pomoc při složení multi import dotazu pomocí dibi tak, aby dibi hodnoty v poli ověřovala.

Díky za rady.

před 9 lety

Milo
Nette Core | 1119

Jestli to dibi umí to nevím.
Když narazíš na limit hosingu při převodu pole, nenarazíš ve finále i s takhle dlouhým SQL řetězcem? Zvážil bych rozdělit to na menší multi inserty a použil reference.

$step = 100;
$cnt = count( $velkaData );
for( $i = 0; $i < $cnt; $i += $step )
{
    $data = array(
        'id'    => array(),
        'jmeno' => array(),
    );

    for( $j = 0; ($j < $step) && ($i + $j < $cnt); $j++ )
    {
        $data['id'][ $j ]    =& $velkaData[ $i + $j ][0];
        $data['jmeno'][ $j ] =& $velkaData[ $i + $j ][1];
    }
    dibi::query("INSERT INTO [tabulka] %m", $data);
}

před 9 lety

westrem
Člen | 398

To co hladas, je operator %ex, expanduje pole.

Jediny problem, ktory vidim je, ze pri vytvarani selectu musi dibi odniekial zobrat nazvy stlpcov.

Normalna struktura pre %ex operator v tomto pripade je:

$a = array (
        array('id'=>1,'name'=>"Pepa"),
        array('id'=>2,'name'=>"Lenka"),
    ..
);
// dotaz
dibi::query("INSERT INTO [table] %ex", $a);
// vysledok
INSERT INTO `table` (`id`, `name`) VALUES (1, 'Pepa'), (2, 'Lenka') ..

Neviem ako narocne by pre teba bolo upravit tvoje pole tak aby bolo ako asociovane. Napada ma vsak jedna finta (nemam vsak otestovane, len sa mi mari, ze to tak funguje v crevach dibi), ze staci ked je prve pole asociovane a z neho zoberie dibi udaje, tzn. takto:

$a = array (
        array('id'=>1,'name'=>"Pepa"),
        array(2,"Lenka"),
    ..
);

To je uz konstantna zlozitost :)

před 9 lety

neologyc
Člen | 13

Dobrý večer,

děkuji za obě rady. Zkouším změnit pole tak, aby v klíčích obsahovalo jméno slouce v DB (id, profese, profese_kod, … ).

Do pole zapisuju v cyklu o 4 průchodech tímto kódem (uvedena jen část)

<?php
    $aData['id'][$i."%i"]= (int) $item['id'];
    $aData['profese'][$i."%s"]= (string) $item->PROFESE['nazev'];
    $aData['profese_kod'][$i."%i"]= (int) $item->PROFESE['kod'];
?>

pole $aData tedy vypadá zhruba takto:

Array
(
    [id] => Array
        (
            [0] => 158000000139897
            [1] => 139000000157945
            [2] => 106000000214478
            [3] => 106000000214698
        )

    [profese] => Array
        (
            [0] => Administrativní pracovník
            [1] => Administrativní pracovník
            [2] => Administrativní pracovník
            [3] => Administrativní pracovník
        )

    [profese_kod] => Array
        (
            [0] => 41159
            [1] => 41159
            [2] => 41159
            [3] => 41159
        )

)

a dibi předávám pole takto

<?php
dibi::test("INSERT INTO [jobs] %m", $aData );
?>

Bohužel dochází k chybě

INSERT INTO `jobs` **Unknown or invalid modifier %m**

Když jsem zkusil před předáním pole do dibi::test na tvrdo definovat pole takto:

<?php
  $aData = array(
        'id' => array(158000000139897,13900000015794,106000000214478,106000000214698),
        'profese' => array("Administrativní pracovník","Administrativní pracovník","Administrativní pracovník","Administrativní pracovník"),
        'profese_kod' => array(41159,41159,41159,41159)
  );
?>

tak to funguje korektně.

Myslím, že problém by mohl být při ověřování typů (string,int) na úrovni dibi, ale netuším, jak to vyřešit.

Díky za rady, jak z tohodle ven :-)

Jarda

Editoval neologyc (24. 10. 2010 22:46)

před 9 lety

Milo
Nette Core | 1119

Jaká verze dibi a jaká databáze?

Neměl by ten zápis do pole být takto?

$aData['id%i'][$i]      = (int)    $item['id'];
$aData['profese%s'][$i]     = (string) $item->PROFESE['nazev'];
$aData['profese_kod%i'][$i] = (int)    $item->PROFESE['kod'];

Editoval Milo (25. 10. 2010 7:53)

před 9 lety

neologyc
Člen | 13

Milo napsal(a):

Jaká verze dibi a jaká databáze?

Neměl by ten zápis do pole být takto?

$aData['id%i'][$i]        = (int)    $item['id'];
$aData['profese%s'][$i]       = (string) $item->PROFESE['nazev'];
$aData['profese_kod%i'][$i]   = (int)    $item->PROFESE['kod'];

Ahoj Milo,

díky za tip, vyřešeno. :-)

Neologyc

Editoval neologyc (25. 10. 2010 8:14)