web-dev-qa-db-fra.com

Un moyen facile d'exporter une table SQL sans accès au serveur ou à phpMyADMIN

J'ai besoin d'un moyen d'exporter puis d'importer facilement des données dans une table MySQL d'un serveur distant vers mon serveur domestique. Je n'ai pas d'accès direct au serveur et aucun utilitaire tel que phpMyAdmin n'est installé. J'ai cependant la possibilité de mettre des scripts PHP sur le serveur.

Comment accéder aux données?

Je pose cette question uniquement pour enregistrer ma façon de le faire

25
Jrgns

Vous pouvez utiliser SQL pour cela:

$file = 'backups/mytable.sql';
$result = mysql_query("SELECT * INTO OUTFILE '$file' FROM `##table##`");

Ensuite, pointez simplement un navigateur ou un client FTP vers le répertoire/fichier (backups/mytable.sql). C'est aussi une belle façon de faire des sauvegardes incrémentielles, étant donné le nom de fichier un horodatage par exemple.

Pour le récupérer dans votre DataBase à partir de ce fichier, vous pouvez utiliser:

$file = 'backups/mytable.sql';
$result = mysql_query("LOAD DATA INFILE '$file' INTO TABLE `##table##`");

L'autre option consiste à utiliser PHP pour appeler une commande système sur le serveur et exécuter 'mysqldump':

$file = 'backups/mytable.sql';
system("mysqldump --opt -h ##databaseserver## -u ##username## -p ##password## ##database | gzip > ".$file);
41
lewis

Je l'ai fait en exportant vers CSV, puis en important avec l'utilitaire disponible. J'aime assez l'utilisation du flux de sortie php: //.

$result = $db_con->query('SELECT * FROM `some_table`');
$fp = fopen('php://output', 'w');
if ($fp && $result) {
    header('Content-Type: text/csv');
    header('Content-Disposition: attachment; filename="export.csv"');
    while ($row = $result->fetch_array(MYSQLI_NUM)) {
        fputcsv($fp, array_values($row));
    }
    die;
}
18
Jrgns

Vous devriez également considérer phpMinAdmin qui n'est qu'un seul fichier, donc c'est facile à télécharger et à configurer.

11
Shinhan

SOLUTION DE TRAVAIL (dernière version à: Export.php + Import.php )

EXPORT_TABLES("localhost","user","pass","db_name");

CODE:

//https://github.com/tazotodua/useful-php-scripts
function EXPORT_TABLES($Host,$user,$pass,$name,  $tables=false, $backup_name=false ){
    $mysqli = new mysqli($Host,$user,$pass,$name); $mysqli->select_db($name); $mysqli->query("SET NAMES 'utf8'");
    $queryTables = $mysqli->query('SHOW TABLES'); while($row = $queryTables->fetch_row()) { $target_tables[] = $row[0]; }   if($tables !== false) { $target_tables = array_intersect( $target_tables, $tables); }
    foreach($target_tables as $table){
        $result = $mysqli->query('SELECT * FROM '.$table);  $fields_amount=$result->field_count;  $rows_num=$mysqli->affected_rows;     $res = $mysqli->query('SHOW CREATE TABLE '.$table); $TableMLine=$res->fetch_row();
        $content = (!isset($content) ?  '' : $content) . "\n\n".$TableMLine[1].";\n\n";
        for ($i = 0, $st_counter = 0; $i < $fields_amount;   $i++, $st_counter=0) {
            while($row = $result->fetch_row())  { //when started (and every after 100 command cycle):
                if ($st_counter%100 == 0 || $st_counter == 0 )  {$content .= "\nINSERT INTO ".$table." VALUES";}
                    $content .= "\n(";
                    for($j=0; $j<$fields_amount; $j++)  { $row[$j] = str_replace("\n","\\n", addslashes($row[$j]) ); if (isset($row[$j])){$content .= '"'.$row[$j].'"' ; }else {$content .= '""';}     if ($j<($fields_amount-1)){$content.= ',';}      }
                    $content .=")";
                //every after 100 command cycle [or at last line] ....p.s. but should be inserted 1 cycle eariler
                if ( (($st_counter+1)%100==0 && $st_counter!=0) || $st_counter+1==$rows_num) {$content .= ";";} else {$content .= ",";} $st_counter=$st_counter+1;
            }
        } $content .="\n\n\n";
    }
    $backup_name = $backup_name ? $backup_name : $name."___(".date('H-i-s')."_".date('d-m-Y').")__Rand".Rand(1,11111111).".sql";
    header('Content-Type: application/octet-stream');   header("Content-Transfer-Encoding: Binary"); header("Content-disposition: attachment; filename=\"".$backup_name."\"");  echo $content; exit;
}
7
T.Todua

Vous pourriez envisager de regarder: http://www.webyog.com Ceci est un excellent outil d'administration graphique, et ils ont une fonctionnalité de tunneling HTTP vraiment soignée (je ne suis pas sûr que ce soit seulement en entreprise qui coûte quelques dollars).

Fondamentalement, vous téléchargez un script qu'ils fournissent dans votre espace Web (script php) et y dirigez le gestionnaire sqlyog et vous pouvez accéder à la ou aux bases de données. Il utilise ce script pour tunneler/proxy les requêtes/requêtes entre votre client domestique et le serveur.

Je connais au moins 1 personne qui utilise cette méthode avec d'excellents résultats.

3
DreamWerx

Si vous avez un accès FTP/SFTP, vous pouvez simplement télécharger phpMyAdmin vous-même.

J'utilise ce petit paquet pour faire des sauvegardes mysql automatisées à partir d'un serveur auquel je n'ai accès que par FTP:
http://www.taw24.de/download/pafiledb.php?PHPSESSID=b48001ea004aacd86f5643a72feb2829&action=viewfile&fid=43&id=1
Le site est en allemand mais le téléchargement contient également une documentation en anglais.

Un google rapide se présente également, mais je ne l'ai pas utilisé moi-même:
http://snipplr.com/view/173/mysql-dump/

3
Lasar

Voici un script PHP que j'ai créé qui sauvegardera toutes les tables de votre base de données. Il est basé sur cela http://davidwalsh.name/backup-mysql-database-php avec quelques améliorations. Tout d'abord, il sera correctement configuré foreign key restrictions.

Dans ma configuration, le script s'exécutera un certain jour de la semaine, disons lundi. Dans le cas où il ne s'est pas exécuté le lundi, il s'exécutera toujours le mardi (par exemple), créant le .sql fichier avec la date du lundi précédent, date à laquelle il était censé s'exécuter. Il effacera .sql fichier d'il y a 4 semaines, il conserve donc toujours les 4 dernières sauvegardes. Voici le code:

<?php

backup_tables();

// backup all tables in db
function backup_tables()
{
    $day_of_backup = 'Monday'; //possible values: `Monday` `Tuesday` `Wednesday` `Thursday` `Friday` `Saturday` `Sunday`
    $backup_path = 'databases/'; //make sure it ends with "/"
    $db_Host = 'localhost';
    $db_user = 'root';
    $db_pass = '';
    $db_name = 'movies_database_1';

    //set the correct date for filename
    if (date('l') == $day_of_backup) {
        $date = date("Y-m-d");
    } else {
        //set $date to the date when last backup had to occur
        $datetime1 = date_create($day_of_backup);
        $date = date("Y-m-d", strtotime($day_of_backup.' -7 days'));
    }

    if (!file_exists($backup_path.$date.'-backup'.'.sql')) {

        //connect to db
        $link = mysqli_connect($db_Host,$db_user,$db_pass);
        mysqli_set_charset($link,'utf8');
        mysqli_select_db($link,$db_name);

        //get all of the tables
        $tables = array();
        $result = mysqli_query($link, 'SHOW TABLES');
        while($row = mysqli_fetch_row($result))
        {
            $tables[] = $row[0];
        }

        //disable foreign keys (to avoid errors)
        $return = 'SET FOREIGN_KEY_CHECKS=0;' . "\r\n";
        $return.= 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";' . "\r\n";
        $return.= 'SET AUTOCOMMIT=0;' . "\r\n";
        $return.= 'START TRANSACTION;' . "\r\n";

        //cycle through
        foreach($tables as $table)
        {
            $result = mysqli_query($link, 'SELECT * FROM '.$table);
            $num_fields = mysqli_num_fields($result);
            $num_rows = mysqli_num_rows($result);
            $i_row = 0;

            //$return.= 'DROP TABLE '.$table.';'; 
            $row2 = mysqli_fetch_row(mysqli_query($link,'SHOW CREATE TABLE '.$table));
            $return.= "\n\n".$row2[1].";\n\n"; 

            if ($num_rows !== 0) {
                $row3 = mysqli_fetch_fields($result);
                $return.= 'INSERT INTO '.$table.'( ';
                foreach ($row3 as $th) 
                { 
                    $return.= '`'.$th->name.'`, '; 
                }
                $return = substr($return, 0, -2);
                $return.= ' ) VALUES';

                for ($i = 0; $i < $num_fields; $i++) 
                {
                    while($row = mysqli_fetch_row($result))
                    {
                        $return.="\n(";
                        for($j=0; $j<$num_fields; $j++) 
                        {
                            $row[$j] = addslashes($row[$j]);
                            $row[$j] = preg_replace("#\n#","\\n",$row[$j]);
                            if (isset($row[$j])) { $return.= '"'.$row[$j].'"' ; } else { $return.= '""'; }
                            if ($j<($num_fields-1)) { $return.= ','; }
                        }
                        if (++$i_row == $num_rows) {
                            $return.= ");"; // last row
                        } else {
                            $return.= "),"; // not last row
                        }   
                    }
                }
            }
            $return.="\n\n\n";
        }

        // enable foreign keys
        $return .= 'SET FOREIGN_KEY_CHECKS=1;' . "\r\n";
        $return.= 'COMMIT;';

        //set file path
        if (!is_dir($backup_path)) {
            mkdir($backup_path, 0755, true);
        }

        //delete old file
        $old_date = date("Y-m-d", strtotime('-4 weeks', strtotime($date)));
        $old_file = $backup_path.$old_date.'-backup'.'.sql';
        if (file_exists($old_file)) unlink($old_file);

        //save file
        $handle = fopen($backup_path.$date.'-backup'.'.sql','w+');
        fwrite($handle,$return);
        fclose($handle);
    }
}

?>
1
Vali Munteanu

J'ai constaté que je n'avais pas suffisamment d'autorisations pour SELECT * INTO OUTFILE. Mais j'ai pu utiliser suffisamment de php (itération et implosion) pour vraiment réduire les boucles imbriquées par rapport à d'autres approches.

$dbfile = tempnam(sys_get_temp_dir(),'sql');

// array_chunk, but for an iterable
function iter_chunk($iterable,$chunksize) {
    foreach ( $iterable as $item ) {
        $ret[] = $item;
        if ( count($ret) >= $chunksize ) {
            yield $ret;
            $ret = array();
        }
    }
    if ( count($ret) > 0 ) {
        yield $ret;
    }
}

function tupleFromArray($assocArr) {
    return '('.implode(',',array_map(function($val) {
        return '"'.addslashes($val).'"';
    },array_values($assocArr))).')';
}

file_put_contents($dbfile,"\n-- Table $table --\n/*\n");
$description = $db->query("DESCRIBE `$table`");
$row = $description->fetch_assoc();
file_put_contents($dbfile,implode("\t",array_keys($row))."\n",FILE_APPEND);
foreach ( $description as $row ) {
    file_put_contents($dbfile,implode("\t",array_values($row))."\n",FILE_APPEND);
}
file_put_contents($dbfile,"*/\n",FILE_APPEND);
file_put_contents($dbfile,"DROP TABLE IF EXISTS `$table`;\n",FILE_APPEND);
file_put_contents($dbfile,array_pop($db->query("SHOW CREATE TABLE `$table`")->fetch_row()),FILE_APPEND);
$ret = $db->query("SELECT * FROM `$table`");
$chunkedData = iter_chunk($ret,1023);
foreach ( $chunkedData as $chunk ) {
    file_put_contents($dbfile, "\n\nINSERT INTO `$table` VALUES " . implode(',',array_map('tupleFromArray',$chunk)) . ";\n", FILE_APPEND );
}
readfile($dbfile);
unlink($dbfile);

Si vous avez des tables avec des clés étrangères, cette approche peut toujours fonctionner si vous les déposez dans le bon ordre, puis les recréez dans le bon ordre (inverse). L'instruction CREATE créera pour vous la dépendance de la clé étrangère. Traverser SELECT * FROM information_schema.referential_constraints pour déterminer cet ordre.

Si vos clés étrangères ont une dépendance circulaire, aucun ordre de suppression ou de création n'est possible. Dans ce cas, vous pourrez suivre l'exemple de phpMyAdmin, qui crée toutes les clés étrangères à la fin. Mais cela signifie également que vous devez ajuster les instructions CREATE.

0
Teepeemm