доступ заборонено для завантаження файлів даних у MySQL


105

Я постійно використовую запити MySQL в PHP, але коли я намагаюся

LOAD DATA INFILE

Я отримую таку помилку

№ 1045 - Доступ заборонено користувачеві 'user' @ 'localhost' (використовуючи пароль: ТАК)

Хтось знає, що це означає?

Відповіді:


197

Я також просто натрапив на це питання. Мені довелося додати LOCALдо мого оператора SQL.

Наприклад, це дає проблему з дозволом:

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

Додайте LOCALдо заяви і питання дозволів має усунутись. Так:

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

12
Це робить іншу річ. Він завантажує ваш файл на сервер у тимчасовий каталог. Іноді це потрібно, але якщо інфіле вже є на сервері MySQL, ви просто працюєте надлишково.
jeffcook2150

1
так, це зробило для мене хитрість, я пересилав порт сервера баз даних через ssh і, мабуть, шукав файл на віддаленому сервері бази даних без МІСЬКОЇ частини
Майк

2
@jeremysawesome для мене це призводить до наступної помилки: Код помилки: 1148 Використовувана команда заборонена в цій версії MySQL. Я спробував відповісти на цю проблему, наприклад, змінивши файл mysql на local-infile = 1, і це теж не вдалося.
OrwellHindenberg

оновлення mySQL до 6.2.5 вирішило цю проблему для мене
OrwellHindenberg

4
можливо, вам також доведеться зателефонувати з mysql за допомогою --local-infileпараметра.
shabbychef

32

У мене була ця проблема. Я обшукував і не знайшов задовільної відповіді. Я підсумовую підсумки результатів своїх пошуків.

Помилка, відхилена в доступі, може означати:

  • 'user' @ 'localhost' не має привілею FILE ( GRANT FILE on *.* to user@'localhost'); або,
  • файл, який ви намагаєтеся завантажити, не існує на машині, на якій працює сервер mysql (якщо використовується LOAD DATA INFILE); або,
  • файл, який ви намагаєтеся завантажити, не існує на вашій локальній машині (якщо ви використовуєте LOAD DATA LOCAL INFILE); або,
  • файл, який ви намагаєтеся завантажити, не є читабельним у всьому світі (вам потрібен файл і всі батьківські каталоги, які можна прочитати у всьому світі: каталог chmod 755; і, chmod 744 file.dat)

+1: Це працювало для мене: файл, який ви намагаєтеся завантажити, не є читабельним у всьому світі (вам потрібен файл і всі батьківські каталоги, які можна прочитати всесвітньо: каталог chmod 755; і, chmod 744 file.dat) . Я не змінив дозволи на всі свої каталоги
gavdotnet

1
Користувач Тетяна вказує, що ви не можете надати FILE привілей на базу даних лише для всього сервера. Команда гранту буде "GRANT FILE on . To user @ 'localhost" ІДЕНТИФІКОВАНО "паролем"); "
JAL

3
@JAL Я думаю, ти маєш на увазі "ВИДАЛИ ФАЙЛ НА *. * Для користувача ..." - ймовірно, символи зірочок були зняті
Євген М


19

Спробуйте скористатися цією командою:

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

Це має спрацювати. Це спрацювало в моєму випадку.


3
ERROR 1148 (42000): The used command is not allowed with this MySQL version
Стюарт

@Stewart, видаліть "local" з вищевказаної команди. Пізніші версії mysql, схоже, не підтримують цей прапор, коли глобальна змінна 'local_infile' змінна встановлена ​​на 'ON' (як нижче). Отже, команда буде такою; mysql> завантажте дані infile 'home / data.txt' у клієнт таблиці; + --------------- + ------- + | Ім'я змінної | Значення | + --------------- + ------- + | local_infile | ON | + --------------- + ------- +
Камран Хайдер

@KamranHyder Звучить так, що ти маєш гарну відповідь до мене. Чому б не додати його як повну відповідь?
Стюарт

10

Переконайтеся, що вашому користувачеві MySQL надано привілей FILE.

Якщо ви перебуваєте на спільному веб-хостингу, є ймовірність, що його заблокує ваш хостинг-провайдер.


На спільному веб-хостингу: чи було б корисно використовувати "ЗАВАНТАЖИТИ ДАНІ МІСЬКОГО ІНФІЛЮ"?
Петро

3

Рядок з Ліона дав мені дуже гарну пораду: У Windows нам потрібно використовувати риски, а не звороту косу рису. Цей код працює для мене:

    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();

2

Я зіткнувся з тим же питанням і вирішив його, виконавши наступні кроки:

  • активувати змінну load_infile
  • дозвіл грандіозного файлу моєму користувальницькому користувачеві mysql
  • деактивувати змінну secure_file_priv (мій файл веб-сервер був завантажений у папку / tmp, що, звичайно, не є захищеною каталогом myslq / var / lib / mysql-file)

Для цього 3-го пункту можна звернутися до: https://dev.mysql.com/doc/refman/5.7/uk/server-system-variables.html#sysvar_secure_file_priv

BR,

AD


2

Це сталося і зі мною, і, незважаючи на те, що я дотримувався всіх кроків, описаних Яміром у своєму пості, я не зміг змусити його працювати.

Файл знаходився у /tmp/test.csv із 777 дозволами. Користувач MySQL мав дозволи на файли, опція LOCAL заборонена моєю версією MySQL, тому я застряг.

Нарешті я зміг вирішити проблему, запустивши:

sudo chown mysql:mysql /tmp/test.csv

2

Я знайшов простий, якщо ви використовуєте командний рядок

Увійти якmysql -u[username] -p[password] --local-infile

тоді SET GLOBAL local_infile = 1;

виберіть свою базу даних за use [db_name]

і, нарешті 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;


Додавання --local-inline мені допомогло. Однак глобальна змінна local_infile у моєму випадку вже була встановлена ​​на ВКЛ. Я думаю, що користувачі краще спочатку розібратися, яке значення вони написали в цю змінну, перш ніж змінювати її.
Євген Майсюк

Для користувачів RDS => Додавання --local-infile допомогло мені в RDS, однак SET GLOBAL local_infile = 1;, схоже , це не працює в RDS, але все одно без цього --local-infileзробив трюк
Факт

0

Я виявив, що завантаження таблиць MySQL може бути швидким і безболісним (я використовував сценарії менеджера моделі python / Django):

1) створити таблицю з усіма стовпцями VARCHAR (n) NULL, наприклад:

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


 2) видаліть заголовки (перший рядок) із csv, а потім завантажте (якщо ви забудете LOCAL, ви отримаєте "# 1045 - доступ заборонено користувачеві" user "@" localhost "(використовуючи пароль: ТАК)"):

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) змінити стовпці:

mysql> ALTER TABLE cw_well2 CHANGE spud_date spud_date DATE;

mysql> ALTER TABLE cw_well2 CHANGE latitude latitude FLOAT;

voilà!


-5

Це, ймовірно, означає, що пароль, який ви ввели, 'user'@'localhost'є неправильним.


1
Я не думаю, що так. Я можу робити інші запити з тим же паролем.
Брайан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.