I am learning MySQL and tried using a LOAD DATA
clause. When I used it as below:
LOAD DATA INFILE \"text.txt\" INTO table mytable;
For mysql 8.0 version you can do this:
mysql.server stop
mysql.server start --secure-file-priv=''
It worked for me on Mac High Sierra.
At macOS Catalina, I followed this steps to set secure_file_priv
1.Stop MySQL service
sudo /usr/local/mysql/support-files/mysql.server stop
2.Restart MYSQL assigning --secure_file_priv system variables
sudo /usr/local/mysql/support-files/mysql.server start --secure-file-priv=YOUR_FILE_DIRECTORY
Note: Adding empty value fix the issue for me, and MYSQL will export data to directory /usr/local/mysql/data/YOUR_DB_TABLE/EXPORT_FILE
sudo /usr/local/mysql/support-files/mysql.server start --secure-file-priv=
Thanks
I had all sorts of problems with this. I was changing my.cnf and all sorts of crazy things that other versions of this problem tried to show.
What worked for me:
The error I was getting
The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
I was able to fix it by opening /usr/local/mysql/support-files/mysql.server and changing the following line:
$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" -- $other_args >/dev/null &
wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
to
$bindir/mysqld_safe --datadir="$datadir" --pid-file="$mysqld_pid_file_path" --secure-file-priv="" $other_args >/dev/null &
wait_for_pid created "$!" "$mysqld_pid_file_path"; return_value=$?
It's working as intended. Your MySQL server has been started with --secure-file-priv option which basically limits from which directories you can load files using LOAD DATA INFILE
.
You may use SHOW VARIABLES LIKE "secure_file_priv";
to see the directory that has been configured.
You have two options:
secure-file-priv
.secure-file-priv
. This must be removed from startup and cannot be modified dynamically. To do this check your MySQL start up parameters (depending on platform) and my.ini.Here is what worked for me in Windows 7 to disable secure-file-priv
(Option #2 from vhu's answer):
services.msc
.C:\ProgramData\MySQL\MySQL Server 5.6
(ProgramData
was a hidden folder in my case).my.ini
file in Notepad.secure-file-priv=""
services.msc
.I created a NodeJS import script if you are running nodeJS and you data is in the following form (double quote + comma and \n new line)
INSERT INTO <your_table> VALUEs( **CSV LINE **)
This one is configured to run on http://localhost:5000/import.
I goes line by line and creates query string
"city","city_ascii","lat","lng","country","iso2","iso3","id"
"Tokyo","Tokyo","35.6850","139.7514","Japan","JP","JPN","1392685764",
...
server.js
const express = require('express'),
cors = require('cors'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
session = require('express-session'),
app = express(),
port = process.env.PORT || 5000,
pj = require('./config/config.json'),
path = require('path');
app.use(bodyParser.json());
app.use(cookieParser());
app.use(cors());
app.use(
bodyParser.urlencoded({
extended: false,
})
);
var Import = require('./routes/ImportRoutes.js');
app.use('/import', Import);
if (process.env.NODE_ENV === 'production') {
// set static folder
app.use(express.static('client/build'));
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, 'client', 'build', 'index.html'));
});
}
app.listen(port, function () {
console.log('Server is running on port: ' + port);
});
ImportRoutes.js
const express = require('express'),
cors = require('cors'),
fs = require('fs-extra'),
byline = require('byline'),
db = require('../database/db'),
importcsv = express.Router();
importcsv.use(cors());
importcsv.get('/csv', (req, res) => {
function processFile() {
return new Promise((resolve) => {
let first = true;
var sql, sqls;
var stream = byline(
fs.createReadStream('../PATH/TO/YOUR!!!csv', {
encoding: 'utf8',
})
);
stream
.on('data', function (line, err) {
if (line !== undefined) {
sql = 'INSERT INTO <your_table> VALUES (' + line.toString() + ');';
if (first) console.log(sql);
first = false;
db.sequelize.query(sql);
}
})
.on('finish', () => {
resolve(sqls);
});
});
}
async function startStream() {
console.log('started stream');
const sqls = await processFile();
res.end();
console.log('ALL DONE');
}
startStream();
});
module.exports = importcsv;
db.js is the config file
const Sequelize = require('sequelize');
const db = {};
const sequelize = new Sequelize(
config.global.db,
config.global.user,
config.global.password,
{
host: config.global.host,
dialect: 'mysql',
logging: console.log,
freezeTableName: true,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
},
}
);
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
Disclaimer: This is not a perfect solution - I am only posting it for devs who are under a timeline and have lots of data to import and are encountering this ridiculous issue. I lost a lot of time on this and I hope to spare another dev the same lost time.