Ошибка БД: 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;

С другими аналогичными парсерерами проблем нет. Что это может быть? Может на саму БД стоят ограничения на запись?


Ответы (0 шт):