Ошибка БД: Table 'metrika_db.undefined' doesn't exist
В парсере (A-Parser) нужные значения собираются, но при выгрузке в БД выпадает
- Ошибка БД: Table 'metrika_db.undefined' doesn't exist.
Код JS
const { BaseParser } = require('a-parser-types');
const mysql2 = require('mysql2/promise');
const querystring = require('querystring');
let connection;
class JS_metrikaToDB extends BaseParser {
static defaultConf = {
version: '1.0.26',
results: {
flat: [
['date', 'Дата'],
['razdel', 'Раздел'],
['vizity_vsego', 'Визиты Всего'],
['vizity_ya_vsego', 'Визиты Яндекс'],
['vizity_google', 'Визиты Google'],
['vizity_ya_ne_brend', 'Небрендовые визиты']
]
},
metrics: 'ym:s:visits',
attribution: 'lastsign',
access_token: 'y0__xDd9qwHGMnkJyDN7r2_EjCOnKvhBxh3ug0k0G27QEjgui1dCEsbsbH2',
robots: 'with_robots',
results_format: "$date;$razdel;$vizity_vsego;$vizity_ya_vsego;$vizity_google;$vizity_ya_ne_brend\n"
};
static editableConf = [
['access_token', ['textfield', 'API key']],
['yesterday_date', ['checkbox', 'Парсим вчерашнюю дату']],
['yesterday_db', ['checkbox', 'Используем базу данных?']],
['metrics', ['combobox', 'Посетители или визиты?',
['ym:s:visits', 'Визиты'],
['ym:s:users', 'Посетители']
]],
['attribution', ['combobox', 'Атрибуция',
['lastsign', 'Последний значимый'],
['first', 'Первый переход']
]]
];
async init() {
connection = await mysql2.createConnection({
host: 'db',
port: "3306",
user: 'parse_db',
password: '5#q@lN%Lc6',
database: 'metrika_db'
});
}
async parse(set, results) {
try {
const params = this.parseQuery(set.query);
const data = await this.fetchData(params);
results.date = data.date;
results.razdel = data.razdel;
results.vizity_vsego = data.vizity_vsego;
results.vizity_ya_vsego = data.vizity_ya_vsego;
results.vizity_google = data.vizity_google;
results.vizity_ya_ne_brend = data.vizity_ya_ne_brend;
if (this.conf.yesterday_db) {
await this.saveToDB(data);
}
return results;
} catch (error) {
this.logger.put(`Ошибка: ${error.message}`);
return results;
}
}
parseQuery(query) {
const parts = query.split('\t');
return {
startDate: this.parseDate(parts[0]),
endDate: this.parseDate(parts[1]),
project: parts[2],
counterId: parts[3],
razdel: parts[4],
regEx: parts[5],
razdelRegEx: parts[6] || '.*'
};
}
async fetchData(params) {
const result = {
date: params.startDate,
razdel: params.razdel,
vizity_vsego: 0,
vizity_ya_vsego: 0,
vizity_google: 0,
vizity_ya_ne_brend: 0
};
const baseParams = {
id: params.counterId,
date1: params.startDate,
date2: params.endDate,
attribution: this.conf.attribution,
accuracy: 'full'
};
const filters = this.buildFilters(params.regEx, params.razdelRegEx);
result.vizity_vsego = await this.getMetric(baseParams, filters.organic);
result.vizity_ya_vsego = await this.getMetric(baseParams, filters.yandex);
result.vizity_google = await this.getMetric(baseParams, filters.google);
result.vizity_ya_ne_brend = await this.getMetric(baseParams, filters.nonBrand);
return result;
}
buildFilters(regEx, razdelRegEx) {
const base = `ym:s:${this.conf.attribution}`;
return {
organic: `${base}TrafficSource=='organic' AND ym:s:startURL=~'${razdelRegEx}'`,
yandex: `${base}SearchEngineRoot=='yandex' AND ym:s:startURL=~'${razdelRegEx}'`,
google: `${base}SearchEngineRoot=='google' AND ym:s:startURL=~'${razdelRegEx}'`,
nonBrand: `${base}SearchPhrase!~'${regEx}' AND ${base}SearchEngineRoot=='yandex' AND ym:s:startURL=~'${razdelRegEx}'`
};
}
async getMetric(params, filter) {
try {
const url = new URL('https://api-metrika.yandex.net/stat/v1/data');
url.search = querystring.stringify({
...params,
metrics: this.conf.metrics,
filters: filter
});
const { success, data } = await this.request('GET', url.toString(), null, {
headers: {
'Authorization': `OAuth ${this.conf.access_token}`,
'Accept': 'application/json'
}
});
if (!success) return 0;
const json = JSON.parse(data);
return json?.totals?.[0] || json?.data?.[0]?.metrics?.[0] || 0;
} catch (error) {
this.logger.put(`Ошибка запроса: ${error.message}`);
return 0;
}
}
async saveToDB(data) {
try {
await connection.execute(
`INSERT INTO ${data.project}
(date, razdel, vizity_vsego, vizity_ya_vsego, vizity_google, vizity_ya_ne_brend)
VALUES (?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
vizity_vsego = VALUES(vizity_vsego),
vizity_ya_vsego = VALUES(vizity_ya_vsego),
vizity_google = VALUES(vizity_google),
vizity_ya_ne_brend = VALUES(vizity_ya_ne_brend)`,
[
data.date,
data.razdel,
data.vizity_vsego,
data.vizity_ya_vsego,
data.vizity_google,
data.vizity_ya_ne_brend
]
);
} catch (error) {
this.logger.put(`Ошибка БД: ${error.message}`);
}
}
parseDate(input) {
if (input.toLowerCase() === 'минус день') {
const date = new Date();
date.setDate(date.getDate() - 1);
return date.toISOString().split('T')[0];
}
return input;
}
}
module.exports = JS_metrikaToDB;
С другими аналогичными парсерерами проблем нет. Что это может быть? Может на саму БД стоят ограничения на запись?
