Как я могу выполнять запросы из файла по одному - PullRequest
0 голосов
/ 09 января 2020

У меня есть большой файл, содержащий несколько SQL запросов, которые мне нужны для запуска на php. Мой проект написан на Laravel v5.6, поэтому я использую Laravel DB Facade для выполнения запросов sql, который находится в моем sql файле.

Код, который запускает Запросы к базе данных:

            $sqlFile=gzopen(__DIR__.'/../sql/queries.sql.gz','r');

            if($sqlFile==false){
                throw new \Exception('Failed to migrate the legacy database');
            }
            echo "Reading ".__DIR__.'/../sql/queries.sql.gz';
            $sql="";
            while (false !== $chunk = gzread($sqlFile, 1000)) {
                $sql.=$chunk;
            }

            gzclose($sqlFile);
            echo "Running Sql";
            DB::connection('etable')->unprepared($sql);

Что я хочу сделать, так это "распределить" мои queries.sql.gz, чтобы запускать запросы sql по одному за раз. Предположим, что запросы могут быть довольно сложными, например:


select * from (
  select * from table1 where age >20
) as seniors JOIN
(
  select * from table1 where age <2
) as children on seniors.child_id=children.id;

Так что я хочу, чтобы сразу после чтения целого запроса из файла немедленно выполнить его, чтобы ускорить процесс. Но как определить, был ли прочитан весь запрос?

Как видите, я запускаю все содержимое файла, а затем выполняю запросы полностью.

Файл gziped имеет следующий размер :

ls -l ./database/sql
σύνολο 116
-rw-rw-r-- 1 pcmagas pcmagas 117868 Ιαν   9 11:10 test_etable.sql.gz

И как только я запускаю фрагмент кода выше, его чтение занимает более 30 минут. Сам код будет выполняться на сценарии миграции, и я планирую запустить его на своем конвейере CI / CD, поэтому я хочу выполнить его максимально быстро.

1 Ответ

0 голосов
/ 16 января 2020

Ну, вам нужна комбинация python и php. С python вам нужно «разбить» файл на меньшие файлы с одним запросом, в то время как в php вы просто сканируете каталог на наличие файлов и выполняете их по порядку.

Для части python вам просто нужна библиотека sqlparse и следующий скрипт:

#! /usr/bin/env python

import sqlparse
import gzip
import os 

file='/home/pcmagas/Kwdikas/etable-api/database/sql/myapp.sql.gz'
dir_path = os.path.dirname(os.path.realpath(file))

file_handler=gzip.open(file,'r')
sql=file_handler.read()
queries=sqlparse.split(sql)

i=1;
for query in queries:
    file=open(dir_path+'_'+str(i)+'_'+'myapp_migration.sql','w')
    file.write(query)
    file.close()
    i+=1

Затем вам нужно выполнить итерацию с помощью php s scandir(), затем прочитать содержимое файла по одному, а затем выполнить каждый запрос один за другим.

...