示例#1
0
    def test_migration_check_success(self, tmpfile, caplogger):
        ddb = Database(provider="sqlite", filename=str(tmpfile))
        init_onetable(ddb)
        s1 = Schema(ddb)
        s1.version = "0.5.0"
        v1 = s1.schema

        def check_cb(check_db):
            with db_session:
                assert (
                    check_db.execute(
                        "select * from sqlite_master").fetchone()[4] ==
                    'CREATE TABLE "bla" ("key" TEXT NOT NULL PRIMARY KEY, "texta" TEXT, "textb" TEXT, "textc" TEXT)'
                )

        m = MakeMigrations(tmpfile, Version("1.3.2"), migrations)
        assert m(check_cb, lambda x: True)
        assert "Error" not in caplogger.read()

        ddb2 = Database(provider="sqlite", filename=str(tmpfile))
        s2 = Schema(ddb2)
        assert (
            s2.schema ==
            """CREATE TABLE "bla" ("key" TEXT NOT NULL PRIMARY KEY, "texta" TEXT, "textb" TEXT, "textc" TEXT)\n"""
        )
        assert s2.version == Version("1.3.2")
示例#2
0
def test_version_set():
    db = Database(provider="sqlite", filename=":memory:")
    s = Schema(file=db)
    assert s.version == Version("0")
    s.version = Version("12.34.56")
    with db_session:
        assert s.db.execute("PRAGMA user_version").fetchone()[0] == 123456
    assert s.version == Version("12.34.56")
示例#3
0
 def test_many_migrations_not_all_file(self, onetablefile):
     m = Migrator(onetablefile, Version("1.3.2"), migrations)
     m()
     with db_session:
         assert (
             m.db.execute("select * from sqlite_master").fetchone()[4] ==
             'CREATE TABLE "bla" ("key" TEXT NOT NULL PRIMARY KEY, "texta" TEXT, "textb" TEXT, "textc" TEXT)'
         )
     assert m.schema.version == Version("1.3.2")
示例#4
0
 def test_one_migration(self, onetable):
     m = Migrator(onetable, Version("1"),
                  {"0.9": ["""INSERT INTO "bla" VALUES("deux")"""]})
     m()
     with db_session:
         assert m.db.execute("select * from bla").fetchall() == [
             ("prems", ),
             ("deux", ),
         ]
     assert m.schema.version == Version("1.0")
示例#5
0
 def test_one_migration_same_version(self, onetable):
     m = Migrator(
         onetable,
         Version("1.5.6"),
         {"1.5.6": ["""INSERT INTO "bla" VALUES("quinze")"""]},
     )
     m()
     with db_session:
         assert m.db.execute("select * from bla").fetchall() == [
             ("prems", ),
             ("quinze", ),
         ]
     assert m.schema.version == Version("1.5.6")
示例#6
0
    def __init__(
            self,
            filename: Union[str, Path],  # chemin vers la ddb
            actual_version: Union[
                Version, str] = None,  # version actuelle (dans les sources)
            migrations: dict = None,  # pool de migrations
    ):
        # migrations = migrations
        self.actual_version = (actual_version if isinstance(
            actual_version, Version) else Version(actual_version))

        self.old_file = Path(filename)  # ddb à faire migrer

        # création d'une base temporaire pour effectuer les migrations
        tmp = tempfile.NamedTemporaryFile(suffix=".sqlite", delete=False)
        tmp.close()
        self.tmp_file = Path(tmp.name)
        shutil.copy(self.old_file, self.tmp_file)  # duplication de la DDB

        # outils pour migrations
        self.tmp_db = Database(provider="sqlite", filename=tmp.name)
        self.schema = Schema(file=self.tmp_db)
        if self.schema.version == self.actual_version:
            logger.info(f"version {self.actual_version}: No migration needed")
            return
        self.migrator = Migrator(self.tmp_db, self.actual_version, migrations)
        logger.info(
            f"starting migrations from version {self.schema.version} to {self.actual_version}"
        )
示例#7
0
 def test_ignore_older_migration_than_base(self, onetable):
     m = Migrator(
         onetable,
         Version("5"),
         {
             "2": ["""INSERT INTO "bla" VALUES("skipped")"""],
             "4": ["""INSERT INTO "bla" VALUES("notskipped")"""],
         },
     )
     m.schema.version = Version("3")
     m()
     with db_session:
         assert m.db.execute("select * from bla").fetchall() == [
             ("prems", ),
             ("notskipped", ),
         ]
     assert m.schema.version == Version("5")
示例#8
0
 def test_restore_backup(self, tmpfile):
     ddb = Database(provider="sqlite", filename=str(tmpfile))
     init_onetable(ddb)
     ddb.disconnect()
     bck_db = tmpfile.read_bytes()
     m = MakeMigrations(tmpfile, Version("1.3.2"),
                        {"1.3.2": "AZEZRT ERTERT"})
     assert not m(lambda x: True, lambda x: True)
     assert tmpfile.read_bytes() == bck_db
示例#9
0
 def test_migrations_same_version_is_cancelled(selfn, tmpfile, caplogger):
     ddb = Database(provider="sqlite", filename=str(tmpfile))
     init_onetable(ddb)
     s1 = Schema(ddb)
     s1.version = "1.3.4"
     m = MakeMigrations(tmpfile, Version("1.3.4"), migrations)
     assert not hasattr(m, "migrator")
     m(lambda: True, lambda: True)
     assert "No migration needed" in caplogger.read()
示例#10
0
 def test_one_migration_not_null_with_default(self, onetable):
     m = Migrator(
         onetable,
         Version("1"),
         {
             "0.9":
             ["""ALTER TABLE bla ADD "textd" TEXT NOT NULL DEFAULT "a" """]
         },
     )
     m()
     with db_session:
         assert m.db.execute("select * from bla").fetchone() == ("prems",
                                                                 "a")
示例#11
0
    def test_migration_check_fail(self, tmpfile, caplogger):
        ddb = Database(provider="sqlite", filename=str(tmpfile))
        init_onetable(ddb)
        s1 = Schema(ddb)
        s1.version = "0.54"

        def check_cb(check_db):
            with db_session:
                assert (
                    check_db.execute(
                        "select * from sqlite_master").fetchone()[4] ==
                    'CREATE TABLE "bla" ("key" TEXT NOT NULL PRIMARY KEY, "textX" TEXT, "textb" TEXT, "textc" TEXT)'
                )

        m = MakeMigrations(tmpfile, Version("1.3.2"), migrations)
        assert not m(check_cb, lambda x: True)
        assert "AssertionError" in caplogger.read()

        # check error then no change
        ddb2 = Database(provider="sqlite", filename=str(tmpfile))
        assert Schema(ddb).schema == Schema(ddb2).schema
        assert Schema(ddb2).version == Version("0.54")
示例#12
0
 def select_migrations(self) -> List[str]:
     """
     Les migrations sont choisies si > à la version de la db et  <= à la version cible
     :returns la liste de str de migrations à effectuer
     """
     selected = []
     schema_v = self.schema.version
     if schema_v == self.version:
         return selected
     for ver, migs in self.migrations.items():
         version = Version(ver)
         if schema_v < version <= self.version:
             selected += migs
     return selected
示例#13
0
 def test_one_migration_not_null_with_initial_value(self, onetable):
     m = Migrator(
         onetable,
         Version("1"),
         {
             "0.9": [
                 """ALTER TABLE bla ADD "textd" TEXT NOT NULL DEFAULT "";""",
                 """UPDATE bla SET textd="b";""",
             ]
         },
     )
     m()
     with db_session:
         assert m.db.execute("select * from bla").fetchone() == ("prems",
                                                                 "b")
示例#14
0
    def test_generate_mapping_fail(self, tmpfile, caplogger):
        ddb = Database(provider="sqlite", filename=str(tmpfile))
        Schema(ddb).version = "0.5.0"

        def check_cb(check_db):
            with db_session:
                check_db.execute("select * from NewTable").fetchall()
            return True

        def generate_cb(generate_db):
            raise IndexError()

        m = MakeMigrations(tmpfile, Version("1.3.2"), {})
        assert not m(check_cb, generate_cb)
        assert "IndexError" in caplogger.read()
示例#15
0
    def test_generate_mapping_success(self, tmpfile):
        ddb = Database(provider="sqlite", filename=str(tmpfile))
        Schema(ddb).version = "0.5.0"

        def check_cb(check_db):
            with db_session:
                check_db.execute("select * from NewTable").fetchall()
            return True

        def generate_cb(generate_db):
            class NewTable(generate_db.Entity):
                aaa = Required(int)

        m = MakeMigrations(tmpfile, Version("1.3.2"), {})
        res = m(check_cb, generate_cb)
        assert res
示例#16
0
    def test_init(self):
        assert Version("3") == Version("3.0.0")
        assert Version("30") == Version("30.0.0")
        assert Version("0") == Version("0.0.0")
        assert Version("3.2") == Version("3.2.0")
        assert Version("30.2") == Version("30.2.0")
        assert Version("30.20") == Version("30.20.0")

        for v in [
                "333", "1.333", "123.1", "123.23.23", "12.233.23", "12.23.323"
        ]:
            with pytest.raises(InvalidVersion):
                Version(v)
示例#17
0
def test_version_get(resources, version):
    base = resources / "db_version" / f"{version}.sqlite"
    if version == "1.2.2":  # exception pour la premiere
        version = "0"
    assert Schema(file=base).version == Version(version)
示例#18
0
 def test_init(self, mm):
     m = mm(Version("1.0.1"), {})
     assert (m._backup_name() ==
             "mycartable_backup-from_0.0.0-to_1.0.1-2017-05-21T12_12_12")
示例#19
0
 def test_parse_int(self):
     for v_int, v_str in versions_values:
         assert Version(v_int) == Version(v_str)
示例#20
0
 def test_to_int(self):
     for v_int, v_str in versions_values[1:]:
         assert Version(v_str).to_int() == v_int
示例#21
0
def test_init_bind_create_file_add_schema_version(tmpfilename):
    ddb = Database()
    init_bind(ddb, filename=tmpfilename, create_db=True)
    s = Schema(ddb)
    assert s.version == Version(schema_version)