code: def test_version_managing(self, data_handler):
      from mindsdb.utilities.exception import EntityNotExistsError
  
      # set up
  
      df = pd.DataFrame(
          [
              {"a": 1, "b": dt.datetime(2020, 1, 1)},
              {"a": 2, "b": dt.datetime(2020, 1, 2)},
              {"a": 1, "b": dt.datetime(2020, 1, 3)},
          ]
      )
      self.set_handler(data_handler, name="pg", tables={"tasks": df})
  
      # ================= retrain cycles =====================
  
      # create folder
      self.run_sql("create database proj")
  
      # -- create model --
      ret = self.run_sql(
          """
                  CREATE model proj.task_model
                  from pg (select * from tasks)
                  PREDICT a
                  using engine='dummy_ml',
                  tag = 'first',
                  join_learn_process=true
              """
      )
      assert ret["NAME"][0] == "task_model"
      assert ret["ENGINE"][0] == "dummy_ml"
      self.wait_predictor("proj", "task_model")
  
      # tag works in create model
      ret = self.run_sql("select * from proj.models")
      assert ret["TAG"][0] == "first"
  
      # use model
      ret = self.run_sql(
          """
               SELECT m.*
                 FROM pg.tasks as t
                 JOIN proj.task_model as m
          """
      )
  
      assert len(ret) == 3
      assert ret.predicted[0] == 42
  
      # -- retrain predictor with tag --
      data_handler.reset_mock()
      ret = self.run_sql(
          """
                  retrain proj.task_model
                  from pg (select * from tasks where a=2)
                  PREDICT b
                  using tag = 'second',
                  join_learn_process=true
              """
      )
      assert ret["NAME"][0] == "task_model"
      assert ret["TAG"][0] == "second"
      self.wait_predictor("proj", "task_model", {"tag": "second"})
  
      # get current model
      ret = self.run_sql("select * from proj.models")
  
      # check target
      assert ret["PREDICT"][0] == "b"
  
      # check label
      assert ret["TAG"][0] == "second"
  
      # use model
      ret = self.run_sql(
          """
               SELECT m.*
                 FROM pg.tasks as t
                 JOIN proj.task_model as m
          """
      )
      assert ret.predicted[0] == 42
  
      # used model has tag 'second'
      models = self.get_models()
      model_id = ret.predictor_id[0]
      assert models[model_id].label == "second"
  
      # -- retrain again with active=0 --
      data_handler.reset_mock()
      self.run_sql(
          """
                  retrain proj.task_model
                  from pg (select * from tasks where a=2)
                  PREDICT a
                  using tag='third', active=0
              """
      )
      self.wait_predictor("proj", "task_model", {"tag": "third"})
  
      ret = self.run_sql("select * from proj.models")
  
      # check target is from previous retrain
      assert ret["PREDICT"][0] == "b"
  
      # use model
      ret = self.run_sql(
          """
               SELECT m.*
                 FROM pg.tasks as t
                 JOIN proj.task_model as m
          """
      )
  
      # used model has tag 'second' (previous)
      models = self.get_models()
      model_id = ret.predictor_id[0]
      assert models[model_id].label == "second"
  
      # ================ working with inactive versions =================
  
      # run 3rd version model and check used model version
      ret = self.run_sql(
          """
               SELECT m.*
                 FROM pg.tasks as t
                 JOIN proj.task_model.3 as m
          """
      )
  
      # 3rd version was used
      models = self.get_models()
      model_id = ret.predictor_id[0]
      assert models[model_id].label == "third"
  
      # one-line query model by version
      ret = self.run_sql(
          "SELECT * from proj.task_model.3 where a=1 and b=2"
      )
      model_id = ret.predictor_id[0]
      assert models[model_id].label == "third"
  
      # check exception: not existing version
      with pytest.raises(EntityNotExistsError) as exc_info:
          self.run_sql(
              "SELECT * from proj.task_model.4 where a=1 and b=2",
          )
  
      # ===================== one-line with 'use database'=======================
  
      # active
      ret = self.run_sql(
          "SELECT * from task_model where a=1 and b=2", database="proj"
      )
      model_id = ret.predictor_id[0]
      assert models[model_id].label == "second"
  
      # inactive
      ret = self.run_sql(
          "SELECT * from task_model.3 where a=1 and b=2",
          database="proj",
      )
      model_id = ret.predictor_id[0]
      assert models[model_id].label == "third"
  
      # ================== managing versions =========================
  
      # check 'show models' command in different combination
      # Show models <from | in> <project> where <expr>
      ret = self.run_sql("Show models")
      assert len(ret) == 1 and ret["NAME"][0] == "task_model"
  
      ret = self.run_sql("Show models from proj")
      assert len(ret) == 1 and ret["NAME"][0] == "task_model"
  
      ret = self.run_sql("Show models in proj")
      assert len(ret) == 1 and ret["NAME"][0] == "task_model"
  
      ret = self.run_sql("Show models where name='task_model'")
      assert len(ret) == 1 and ret["NAME"][0] == "task_model"
  
      # model is not exists
      ret = self.run_sql("Show models from proj where name='xxx'")
      assert len(ret) == 0
  
      # ----------------
  
      # See all versions
      ret = self.run_sql("select * from proj.models_versions")
      # we have all tags in versions
      assert set(ret["TAG"]) == {"first", "second", "third"}
  
      # Set active selected version
      self.run_sql(
          """
             update proj.models_versions
             set active=1
             where version=1 and name='task_model'
          """
      )
  
      # get active version
      ret = self.run_sql(
          "select * from proj.models_versions where active = 1"
      )
      assert ret["TAG"][0] == "first"
  
      # use active version ?
  
      # Delete specific version
      self.run_sql(
          """
             delete from proj.models_versions
             where version=2
             and name='task_model'
          """
      )
  
      # deleted version not in list
      ret = self.run_sql("select * from proj.models_versions")
      assert len(ret) == 2
      assert "second" not in ret["TAG"]
  
      # try to use deleted version
      with pytest.raises(EntityNotExistsError) as exc_info:
          self.run_sql(
              "SELECT * from proj.task_model.2 where a=1",
          )
  
      # exception with deleting active version
      with pytest.raises(Exception) as exc_info:
          self.run_sql(
              """
                 delete from proj.models_versions
                 where version=1
                 and name='task_model'
              """
          )
      assert "Can't remove active version" in str(exc_info.value)
  
      # exception with deleting non-existing version
      with pytest.raises(Exception) as exc_info:
          self.run_sql(
              """
                 delete from proj.models_versions
                 where version=11
                 and name='task_model'
              """
          )
      assert "is not found" in str(exc_info.value)
  
      # ----------------------------------------------------
  
      # retrain without all params
      self.run_sql(
          """
                  retrain proj.task_model
              """
      )
      self.wait_predictor("proj", "task_model", {"version": "4"})
  
      # ----------------------------------------------------
  
      # drop predictor and check model is deleted and no versions
      self.run_sql("drop model proj.task_model")
      ret = self.run_sql("select * from proj.models")
      assert len(ret) == 0
  
      # versions are also deleted
      ret = self.run_sql("select * from proj.models_versions")
      assert len(ret) == 0
  
imports: from unittest.mock import patch
  import datetime
  import time
  import pytest
  import pandas
  from mindsdb_sql import parse_sql
  from .executor_test_base import BaseExecutorDummyML
label_desc: Use image node_id 4 for calling the TestProjectStructure obj's underlying member method code with example usage: obj.test_version_managing(data_handler) without return types