accès refusé pour charger le fichier de données dans MySQL

105

J'utilise des requêtes MySQL tout le temps en PHP, mais quand j'essaye

LOAD DATA INFILE

J'obtiens l'erreur suivante

# 1045 - Accès refusé pour l'utilisateur 'user' @ 'localhost' (en utilisant le mot de passe: OUI)

Est-ce que quelqu'un sait ce que cela signifie?

Brian
la source

Réponses:

197

Je viens de rencontrer ce problème également. J'ai dû ajouter LOCALà mon instruction SQL.

Par exemple, cela pose le problème d'autorisation:

LOAD DATA INFILE '{$file}' INTO TABLE {$table}

Ajoutez LOCALà votre déclaration et le problème des autorisations devrait disparaître. Ainsi:

LOAD DATA LOCAL INFILE '{$file}' INTO TABLE {$table}
jeremysawesome
la source
12
Cela fait une chose différente. Il télécharge votre fichier sur le serveur dans un répertoire temporaire. Cela est parfois nécessaire, mais si le fichier est déjà sur le serveur MySQL, vous effectuez simplement un travail redondant.
jeffcook2150
1
oui, cela a fait l'affaire pour moi, je transmettais le port du serveur de base de données via ssh et je suppose qu'il recherchait le fichier sur le serveur de base de données distant sans la partie LOCAL
mike
2
@jeremysawesome pour moi, cela produit l'erreur suivante: Code d'erreur: 1148 La commande utilisée n'est pas autorisée avec cette version de MySQL. J'ai essayé quelques réponses à ce problème, telles que la modification du fichier mysql en local-infile = 1 et cela a également échoué.
OrwellHindenberg
une mise à jour de mySQL vers 6.2.5 a résolu ce problème pour moi
OrwellHindenberg
4
vous devrez peut-être également appeler mysql avec l' --local-infileoption.
shabbychef
32

J'ai eu ce problème. J'ai cherché partout et je n'ai pas trouvé de réponse satisfaisante. Je résume ci-dessous les résultats de mes recherches.

L'erreur d'accès refusé peut signifier que:

  • 'user' @ 'localhost' n'a pas le privilège FILE ( GRANT FILE on *.* to user@'localhost'); ou,
  • le fichier que vous essayez de charger n'existe pas sur la machine exécutant le serveur mysql (si vous utilisez LOAD DATA INFILE); ou,
  • le fichier que vous essayez de charger n'existe pas sur votre machine locale (si vous utilisez LOAD DATA LOCAL INFILE); ou,
  • le fichier que vous essayez de charger n'est pas lisible par tout le monde (vous avez besoin que le fichier et tous les répertoires parents soient lisibles par le monde: répertoire chmod 755; et, chmod 744 file.dat)
Yamir Encarnacion
la source
+1: Cela a fonctionné pour moi: le fichier que vous essayez de charger n'est pas lisible par tout le monde (vous avez besoin que le fichier et tous les répertoires parents soient lisibles par le monde: répertoire chmod 755; et, chmod 744 file.dat) . Je n'avais pas changé les autorisations sur tous mes répertoires
gavdotnet
1
L'utilisateur Tatiana souligne que vous ne pouvez pas accorder le privilège FILE par base de données, uniquement pour l'ensemble du serveur. La commande grant serait "GRANT FILE on . To user @ 'localhost' IDENTIFIED BY 'password');"
JAL
3
@JAL Je pense que vous voulez dire "GRANT FILE ON *. * To user ..." - probablement les astérisques ont été supprimés
Eugene M
comme @Eugene M l'a dit, cela donne une erreur Utilisation incorrecte de DB GRANT et GLOBAL PRIVILEGES
Accountant م
19

Essayez d'utiliser cette commande:

load data local infile 'home/data.txt' into table customer;

Cela devrait fonctionner. Cela a fonctionné dans mon cas.

shreyas-agrawal
la source
3
ERROR 1148 (42000): The used command is not allowed with this MySQL version
Stewart le
@Stewart, veuillez supprimer «local» de la commande ci-dessus. Les versions ultérieures de mysql ne semblent pas prendre en charge cet indicateur lorsque la variable globale «local_infile» est définie sur «ON» (comme ci-dessous). La commande sera donc; mysql> charge le fichier de données 'home / data.txt' dans la table customer; + --------------- + ------- + | Nom_variable | Valeur | + --------------- + ------- + | local_infile | ON | + --------------- + ------- +
Kamran Hyder
@KamranHyder On dirait que vous avez une bonne réponse à moi. Pourquoi ne pas l'ajouter comme réponse complète?
Stewart
10

Assurez-vous que votre utilisateur MySQL dispose du privilège FILE.

Si vous utilisez un hébergement Web partagé, il est possible que cela soit bloqué par votre fournisseur d'hébergement.

Tanerkay
la source
Sur un hébergement mutualisé: serait-il utile d'utiliser "LOAD DATA LOCAL INFILE"?
Peter
3

La chaîne de Lyon m'a donné un très bon conseil: sous Windows, il faut utiliser des slahes et non des backslashes. Ce code fonctionne pour moi:

    File tempFile = File.createTempFile(tableName, ".csv");
    FileUtils.copyInputStreamToFile(data, tempFile);

    JdbcTemplate template = new JdbcTemplate(dataSource);
    String path = tempFile.getAbsolutePath().replace('\\', '/');
    int rows = template.update(MessageFormat
            .format("LOAD DATA LOCAL INFILE ''{0}'' INTO TABLE {1} FIELDS TERMINATED BY '',''",
                    path, tableName));
    logger.info("imported {} rows into {}", rows, tableName);

    tempFile.delete();
Matthias Wuttke
la source
2

J'ai rencontré le même problème et je l'ai résolu en suivant ces étapes:

  • activer la variable load_infile
  • grande autorisation de fichier à mon utilisateur mysql personnalisé
  • désactiver la variable secure_file_priv (mon fichier a été téléchargé par le serveur web dans le dossier / tmp qui n'est bien sûr pas le répertoire sécurisé de myslq / var / lib / mysql-file)

Pour ce 3ème point, vous pouvez vous référer à: https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_secure_file_priv

BR,

UN D

user7996813
la source
2

Cela m'est arrivé aussi et malgré avoir suivi toutes les étapes décrites par Yamir dans son message, je n'ai pas pu le faire fonctionner.

Le fichier se trouvait dans /tmp/test.csv avec 777 autorisations. L'utilisateur MySQL avait des autorisations de fichier, l'option LOCAL n'était pas autorisée par ma version MySQL, donc j'étais bloqué.

Enfin, j'ai pu résoudre le problème en exécutant:

sudo chown mysql:mysql /tmp/test.csv
Giacomo
la source
2

J'en ai trouvé un facile si vous utilisez la ligne de commande

Se connecter en tant quemysql -u[username] -p[password] --local-infile

puis SET GLOBAL local_infile = 1;

sélectionnez votre base de données en use [db_name]

et enfin LOAD DATA LOCAL INFILE 'C:\\Users\\shant\\Downloads\\data-1573708892247.csv' INTO TABLE visitors_final_test FIELDS TERMINATED BY ','LINES TERMINATED BY '\r \n' IGNORE 1 LINES;

Shantanu Khond
la source
L'ajout de --local-inline m'a aidé. Cependant, la variable globale local_infile était déjà définie sur ON dans mon cas. Je pense que les utilisateurs préfèrent d'abord déterminer la valeur qu'ils ont écrite dans cette variable avant de la modifier.
Eugene Maysyuk le
Pour les utilisateurs de RDS => L'ajout de --local-infile m'a aidé sur RDS, mais SET GLOBAL local_infile = 1;ne semble pas fonctionner dans RDS, mais de toute façon, cela a --local-infilefait l'affaire
Fait
0

J'ai découvert que le chargement de tables MySQL pouvait être rapide et indolore (j'utilisais des scripts de gestionnaire de modèles python / Django):

1) créer une table avec toutes les colonnes VARCHAR (n) NULL par exemple:

mysql> CREATE TABLE cw_well2( api VARCHAR(10) NULL,api_county VARCHAR(3) NULL);


 2) supprimez les en-têtes (première ligne) de csv, puis chargez (si vous oubliez le LOCAL, vous obtiendrez «# 1045 - Accès refusé pour l'utilisateur 'user' @ 'localhost' (en utilisant le mot de passe: OUI)»):

mysql> LOAD DATA LOCAL INFILE "/home/magula6/cogswatch2/well2.csv" INTO TABLE cw_well2 FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'     -> ; Query OK, 119426 rows affected, 19962 warnings  (3.41 sec)


 3) modifier les colonnes:

mysql> ALTER TABLE cw_well2 CHANGE spud_date spud_date DATE;

mysql> ALTER TABLE cw_well2 CHANGE latitude latitude FLOAT;

voilà!

magula
la source
-5

Cela signifie probablement que le mot de passe que vous avez fourni 'user'@'localhost'est incorrect.

David Grant
la source
1
Je ne pense pas. Je peux faire d'autres requêtes avec le même mot de passe.
Brian