odmowa dostępu do pliku danych ładowania w MySQL

105

Używam zapytań MySQL cały czas w PHP, ale kiedy próbuję

LOAD DATA INFILE

Otrzymuję następujący błąd

# 1045 - Odmowa dostępu dla użytkownika „user” @ „localhost” (używając hasła: TAK)

Czy ktokolwiek wie, co to znaczy?

Brian
źródło

Odpowiedzi:

197

Właśnie napotkałem ten problem. Musiałem dodać LOCALdo mojej instrukcji SQL.

Na przykład powoduje to problem z uprawnieniami:

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

Dodaj LOCALdo swojego oświadczenia, a problem z uprawnieniami powinien zniknąć. Tak jak to:

LOAD DATA LOCAL INFILE '{$file}' INTO TABLE {$table}
jeremysawesome
źródło
12
To robi inną rzecz. Przesyła plik na serwer w katalogu tymczasowym. Czasami jest to konieczne, ale jeśli plik infile jest już na serwerze MySQL, po prostu wykonujesz zbędną pracę.
jeffcook2150
1
tak, to załatwiło sprawę, przekierowałem port serwera bazy danych przez ssh i wydaje mi się, że szukałem pliku na zdalnym serwerze bazy danych bez części LOCAL
mike
2
@jeremysawesome dla mnie powoduje to następujący błąd: Kod błędu: 1148 Użyte polecenie nie jest dozwolone w tej wersji MySQL. Próbowałem kilku odpowiedzi na ten problem, takich jak modyfikacja pliku mysql do local-infile = 1 i to również się nie powiodło.
OrwellHindenberg
aktualizacja mySQL do wersji 6.2.5 rozwiązała ten problem za mnie
OrwellHindenberg
4
może być również konieczne wywołanie mysql z --local-infileopcją.
shabbychef
32

Miałem ten problem. Rozejrzałem się i nie znalazłem satysfakcjonującej odpowiedzi. Poniżej podsumowuję wyniki moich poszukiwań.

Błąd odmowy dostępu może oznaczać, że:

  • „użytkownik” @ „localhost” nie ma uprawnienia do PLIKU ( GRANT FILE on *.* to user@'localhost'); lub,
  • plik, który próbujesz załadować, nie istnieje na komputerze z uruchomionym serwerem mysql (jeśli używasz LOAD DATA INFILE); lub,
  • plik, który próbujesz załadować, nie istnieje na twoim lokalnym komputerze (jeśli używasz LOAD DATA LOCAL INFILE); lub,
  • plik, który próbujesz załadować, nie jest czytelny dla wszystkich (potrzebujesz tego pliku i wszystkich katalogów nadrzędnych, aby były czytelne dla wszystkich: katalog chmod 755; i chmod 744 file.dat)
Yamir Encarnacion
źródło
+1: To zadziałało dla mnie: plik, który próbujesz załadować, nie jest czytelny dla wszystkich (potrzebujesz pliku i wszystkich katalogów nadrzędnych, aby były czytelne dla wszystkich: katalog chmod 755; i chmod 744 plik.dat) . Nie zmieniłem uprawnień do wszystkich moich katalogów
gavdotnet,
1
Użytkownik Tatiana zwraca uwagę, że nie można nadać uprawnienia do PLIKU dla każdej bazy danych, tylko dla całego serwera. Poleceniem grant byłoby „GRANT FILE on . To user @ 'localhost' IDENTIFIED BY 'password');"
JAL
3
@JAL Myślę, że masz na myśli „PRZYZNAJ PLIK NA *. * Użytkownikowi ...” - prawdopodobnie znaki gwiazdki zostały usunięte
Eugene M
jak powiedział @Eugene M, powoduje to błąd Nieprawidłowe użycie DB GRANT i GLOBAL PRIVILEGES
Księgowy م
19

Spróbuj użyć tego polecenia:

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

To powinno działać. W moim przypadku zadziałało.

shreyas-agrawal
źródło
3
ERROR 1148 (42000): The used command is not allowed with this MySQL version
Stewart
@Stewart, usuń „local” z powyższego polecenia. Późniejsze wersje mysql nie obsługują tej flagi, gdy zmienna globalna „local_infile” jest ustawiona na „ON” (jak poniżej). Rozkaz będzie zatem; mysql> załaduj plik danych „home / data.txt” do tabeli customer; + --------------- + ------- + | Variable_name | Wartość | + --------------- + ------- + | plik_lokalny | ON | + --------------- + ------- +
Kamran Hyder
@KamranHyder Wygląda na to, że masz dla mnie dobrą odpowiedź. Dlaczego nie dodać tego jako pełnej odpowiedzi?
Stewart
10

Upewnij się, że Twój użytkownik MySQL ma przyznane uprawnienie do PLIKU.

Jeśli korzystasz z hostingu współdzielonego, istnieje szansa, że ​​zostanie to zablokowane przez dostawcę usług hostingowych.

tanerkay
źródło
Na współdzielonym hostingu internetowym: czy przydałoby się użycie opcji „LOAD DATA LOCAL INFILE”?
Peter
3

Sznurek z Lyonu dał mi bardzo dobrą wskazówkę: w systemie Windows musimy używać slahes, a nie backslashes. Ten kod działa dla mnie:

    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
źródło
2

Napotkałem ten sam problem i rozwiązałem go, wykonując następujące kroki:

  • aktywuj zmienną load_infile
  • wielkie uprawnienia do plików dla mojego niestandardowego użytkownika mysql
  • dezaktywuj zmienną secure_file_priv (mój plik został przesłany przez serwer sieciowy do folderu / tmp, który oczywiście nie jest zabezpieczonym katalogiem myslq / var / lib / mysql-file)

W przypadku tego trzeciego punktu możesz zapoznać się z: https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_secure_file_priv

BR,

OGŁOSZENIE

user7996813
źródło
2

Przydarzyło mi się to również i pomimo wykonania wszystkich kroków opisanych przez Yamira w jego poście nie mogłem sprawić, by to zadziałało.

Plik znajdował się w /tmp/test.csv z 777 uprawnieniami. Użytkownik MySQL miał uprawnienia do plików, opcja LOCAL nie była dozwolona przez moją wersję MySQL, więc utknąłem.

Wreszcie udało mi się rozwiązać problem, uruchamiając:

sudo chown mysql:mysql /tmp/test.csv
Giacomo
źródło
2

Znalazłem łatwy, jeśli używasz wiersza poleceń

Zaloguj się jakomysql -u[username] -p[password] --local-infile

następnie SET GLOBAL local_infile = 1;

wybierz swoją bazę danych przez use [db_name]

i w końcu 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
źródło
Pomogło mi dodanie --local-inline. Jednak zmienna globalna local_infile była już ustawiona na ON w moim przypadku. Myślę, że użytkownicy powinni najpierw dowiedzieć się, jaką wartość zapisali w tej zmiennej, zanim ją zmodyfikują.
Eugene Maysyuk
Dla użytkowników RDS => Dodanie --local-plik_we pomógł mi na RDS, jednak SET GLOBAL local_infile = 1;nie wydaje się do pracy w RDS, ale w każdym razie, że nie --local-infilewystarczyły
Fakt
0

Odkryłem, że ładowanie tabel MySQL może być szybkie i bezbolesne (używałem skryptów menedżera modeli Python / Django):

1) utwórz tabelę ze wszystkimi kolumnami VARCHAR (n) NULL np:

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


 2) usuń nagłówki (pierwsza linia) z csv, a następnie załaduj (jeśli zapomnisz LOCAL, otrzymasz „# 1045 - Odmowa dostępu dla użytkownika 'user' @ 'localhost' (używając hasła: TAK)”):

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) zmień kolumny:

mysql> ALTER TABLE cw_well2 CHANGE spud_date spud_date DATE;

mysql> ALTER TABLE cw_well2 CHANGE latitude latitude FLOAT;

voilà!

magula
źródło
-5

Prawdopodobnie oznacza to, że podane hasło 'user'@'localhost'jest nieprawidłowe.

David Grant
źródło
1
Nie sądzę. Mogę wykonywać inne zapytania, używając tego samego hasła.
Brian