Как мне обрабатывать динамически генерируемые таблицы базы данных в Phalcon?

Я создаю веб-приложение для нашего менеджера по андеррайтингу, чтобы создать и протестировать ее рейтинговые схемы для различных страховых продуктов.

Редактор позволяет пользователю добавлять и удалять шаги в процессе расчета, и каждый такой шаг может зависеть от нескольких различных рейтинговых факторов (возраст водителя, возраст транспортного средства и т. Д.). Количество факторов на шаг не фиксировано, поэтому первый шаг может зависеть только от одного рейтингового фактора, а следующий может зависеть от четырех различных рейтинговых факторов.

Моя реализация использует таблицу базы данных для хранения каждого шага в таблице со следующей структурой:

 id  | schemeId  | stepnumber  |  stepname  |  calculationtable
-----------------------------------------------------------------
     |           |             |            |

id это первичный ключ, schemeId идентификатор схемы, которой принадлежит этот шаг, stepnumber используется для упорядочения шагов (их можно изменить в редакторе), stepname это просто метка для шага, а `таблица расчета содержит имя таблицы, которая содержит фактическую информацию о факторе рейтинга для этого шага.

Создание модели для этой таблицы в Phalcon - пустяк и работает отлично. Проблема в расчете таблицы. Когда создается новый шаг, в эту таблицу шагов вставляется строка, и создается новая таблица с таким именем, как scheme1step10, Структура этой таблицы является динамической в ​​зависимости от количества факторов, от которых зависит этот шаг в расчете. Редактор позволит пользователю добавлять и удалять рейтинговые коэффициенты для каждого шага, поэтому количество столбцов в каждой из этих таблиц будет различным и будет меняться со временем. Из-за динамического характера этих таблиц я не могу понять, как я могу создать модель для них.

У меня была предыдущая версия этого редактора, с которой я экспериментировал несколько лет назад, в котором не использовалась инфраструктура, и получение данных для этой таблицы выглядело так:

public function getSteptable()
{
    $returnval=false;
    $result=mysql_query("SHOW COLUMNS FROM ".$this->getCalculationtable());
    if($result!=false)
    {
        for($loop=0;$loop<mysql_num_rows($result);$loop++)
        {
            $row=mysql_fetch_array($result);
            $colnames[$loop]=$row['Field'];
        }
        $rowsresult=mysql_query("SELECT * FROM ".$this->getCalculationtable());
        if($rowsresult!=false)
        {
            for($loop=0;$loop<mysql_num_rows($rowsresult);$loop++)
            {
                $row=mysql_fetch_array($rowsresult);
                foreach($colnames as $colname)
                {
                    $returnval[$loop][$colname]=$row[$colname];
                }
            }
        }
    }
    return $returnval;
}

Пожалуйста, игнорируйте тот факт, что этот код использует устаревшие mysql_ функции.

Итак, мой вопрос, как я могу воссоздать подобные вещи в Phalcon? Похоже, я не могу использовать PHQL, так как он, кажется, полагается на модель, существующую для рассматриваемой таблицы - я получаю ошибку Model 'scheme1step1' could not be loaded когда я пытаюсь $steptable=$this->modelsManager->executeQuery("SELECT * FROM $steptablename") ($steptablename взят из другой таблицы и изначально генерируется приложением, поэтому я думаю, что он должен быть защищен от возможности внедрения SQL). Нужно ли использовать необработанный SQL, как показано здесь, или это также зависит от наличия существующей модели? Или мне нужно будет создать свою собственную модель, которая не использует ORM Phalcon для этих динамических таблиц? И если это так, могу ли я использовать соединение с БД, хранящееся в контейнере DI, без проблем?

1 ответ

Это очень интересная проблема.

Я считаю, что этого можно добиться с помощью "динамической" Model, modelsManager и пользовательской стратегии метаданных, хотя это только моя теория, которая может работать, а может и не работать вообще, или просто вести вас в правильном направлении.


  1. Создайте автозагрузчик, который динамически создаст для вас класс circuit1step1 с помощью eval() или чего-то похожего на Zend_CodeGenerator_Php_Class() - сделайте его простым, например:

    eval ('схема схемы1step1 extends \Phalcon\Mvc\Model {} ');

  2. Создайте собственную стратегию MetaData, аналогичную Introspection (возможно, расширьте ее), которая будет работать как прокси-объект "поймать все"

  3. Если стратегия обнаруживает, что была вызвана обычная модель, просто передайте ее родителю Introspection
  4. Если он обнаруживает Model_step1 Model, проинструктируйте его соответствующим образом о карте столбцов таблицы, возможно, с помощью \Phalcon\Db\Dialect\Mysql или снова Introspection (зависит от других потребностей)

Или просто сделайте шаги 2,3,4 в шаге 1:D Удачи!

PS. Я перестал комментировать идею динамического "разделения" таких таблиц, которая выглядит неправильно, вместо этого она сосредоточена на реальной проблеме.

Другие вопросы по тегам