Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-peewee-migrate for
openSUSE:Factory checked in at 2026-01-08 15:28:19
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-peewee-migrate (Old)
and /work/SRC/openSUSE:Factory/.python-peewee-migrate.new.1928 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-peewee-migrate"
Thu Jan 8 15:28:19 2026 rev:2 rq:1325864 version:1.14.3
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-peewee-migrate/python-peewee-migrate.changes
2024-09-24 17:35:10.945867072 +0200
+++
/work/SRC/openSUSE:Factory/.python-peewee-migrate.new.1928/python-peewee-migrate.changes
2026-01-08 15:29:02.449082758 +0100
@@ -1,0 +2,8 @@
+Wed Dec 3 22:09:20 UTC 2025 - Guang Yee <[email protected]>
+
+- Update to 1.14.3
+ - feat: drop py3.8, update indexes
+ - fix: ignore peewee defaults for migrations
+ - feat: tune migrations
+
+-------------------------------------------------------------------
Old:
----
peewee_migrate-1.13.0.tar.gz
New:
----
peewee_migrate-1.14.3.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-peewee-migrate.spec ++++++
--- /var/tmp/diff_new_pack.mL30lq/_old 2026-01-08 15:29:04.265158142 +0100
+++ /var/tmp/diff_new_pack.mL30lq/_new 2026-01-08 15:29:04.269158308 +0100
@@ -1,7 +1,7 @@
#
# spec file for package python-peewee-migrate
#
-# Copyright (c) 2024 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -24,7 +24,7 @@
%{?sle15_python_module_pythons}
Name: python-peewee-migrate
-Version: 1.13.0
+Version: 1.14.3
Release: 0
Summary: Support for migrations in Peewee ORM
License: MIT
++++++ peewee_migrate-1.13.0.tar.gz -> peewee_migrate-1.14.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/PKG-INFO
new/peewee_migrate-1.14.3/PKG-INFO
--- old/peewee_migrate-1.13.0/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
+++ new/peewee_migrate-1.14.3/PKG-INFO 1970-01-01 01:00:00.000000000 +0100
@@ -1,27 +1,28 @@
-Metadata-Version: 2.1
+Metadata-Version: 2.4
Name: peewee-migrate
-Version: 1.13.0
+Version: 1.14.3
Summary: Support for migrations in Peewee ORM
-Home-page: https://github.com/klen/peewee_migrate
License: MIT
+License-File: LICENSE
Keywords: peewee,migrations,orm
Author: Kirill Klenov
Author-email: [email protected]
-Requires-Python: >=3.8,<4.0
+Requires-Python: >=3.10,<4.0
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.8
-Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
+Classifier: Programming Language :: Python :: 3.13
+Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Utilities
Requires-Dist: click
Requires-Dist: peewee (>=3,<4)
+Project-URL: Homepage, https://github.com/klen/peewee_migrate
Project-URL: Repository, https://github.com/klen/peewee_migrate
Description-Content-Type: text/x-rst
@@ -59,7 +60,7 @@
Requirements
=============
-- peewee >= 3.8
+- peewee >= 3.10
Dependency Note
---------------
@@ -67,7 +68,8 @@
- For ``Peewee<3.0`` please use ``Peewee-Migrate==0.14.0``
- For ``Python 3.0-3.6`` please use ``Peewee-Migrate==1.1.6``
- For ``Python 3.7`` please use ``Peewee-Migrate==1.6.6``
-- For ``Python 3.8+`` please use ``Peewee-Migrate>=1.12.1``
+- For ``Python 3.8, 3.9`` please use ``Peewee-Migrate>=1.13.0``
+- For ``Python 3.10+`` please use ``Peewee-Migrate>=1.14+``
.. _installation:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/README.rst
new/peewee_migrate-1.14.3/README.rst
--- old/peewee_migrate-1.13.0/README.rst 2024-07-17 12:13:20.295652200
+0200
+++ new/peewee_migrate-1.14.3/README.rst 1970-01-01 01:00:00.000000000
+0100
@@ -32,7 +32,7 @@
Requirements
=============
-- peewee >= 3.8
+- peewee >= 3.10
Dependency Note
---------------
@@ -40,7 +40,8 @@
- For ``Peewee<3.0`` please use ``Peewee-Migrate==0.14.0``
- For ``Python 3.0-3.6`` please use ``Peewee-Migrate==1.1.6``
- For ``Python 3.7`` please use ``Peewee-Migrate==1.6.6``
-- For ``Python 3.8+`` please use ``Peewee-Migrate>=1.12.1``
+- For ``Python 3.8, 3.9`` please use ``Peewee-Migrate>=1.13.0``
+- For ``Python 3.10+`` please use ``Peewee-Migrate>=1.14+``
.. _installation:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/peewee_migrate/auto.py
new/peewee_migrate-1.14.3/peewee_migrate/auto.py
--- old/peewee_migrate-1.13.0/peewee_migrate/auto.py 2024-07-17
12:13:20.295652200 +0200
+++ new/peewee_migrate-1.14.3/peewee_migrate/auto.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,24 +1,15 @@
"""Automatically create migrations."""
+
from __future__ import annotations
-from typing import (
- TYPE_CHECKING,
- Any,
- Callable,
- Dict,
- Final,
- Iterable,
- List,
- Optional,
- Type,
- Union,
- cast,
-)
+from typing import TYPE_CHECKING, Any, Callable, Final, cast
import peewee as pw
-from playhouse import postgres_ext
+from playhouse import postgres_ext # type: ignore[]
from playhouse.reflection import Column as VanilaColumn
+from peewee_migrate.utils import model_fields_gen
+
if TYPE_CHECKING:
from .migrator import Migrator
from .types import TModelType, TParams
@@ -59,17 +50,17 @@
def arrayf_to_params(f: postgres_ext.ArrayField):
- inner_field: pw.Field = f._ArrayField__field
- module = FIELD_MODULES_MAP.get(inner_field.__class__.__name__, "pw")
- return {
- "field_class": f"{module}.{inner_field.__class__.__name__}",
- "field_kwargs": repr(Column(inner_field).get_field_parameters()),
- "dimensions": f.dimensions,
- "convert_values": f.convert_values
- }
+ inner_field: pw.Field = f._ArrayField__field
+ module = FIELD_MODULES_MAP.get(inner_field.__class__.__name__, "pw")
+ return {
+ "field_class": f"{module}.{inner_field.__class__.__name__}",
+ "field_kwargs": repr(Column(inner_field).get_field_parameters()),
+ "dimensions": f.dimensions,
+ "convert_values": f.convert_values,
+ }
-FIELD_TO_PARAMS: Dict[Type[pw.Field], Callable[[Any], TParams]] = {
+FIELD_TO_PARAMS: dict[type[pw.Field], Callable[[Any], TParams]] = {
pw.CharField: lambda f: {"max_length": f.max_length},
pw.DecimalField: lambda f: {
"auto_round": f.auto_round,
@@ -86,7 +77,7 @@
class Column(VanilaColumn):
"""Get field's migration parameters."""
- field_class: Type[pw.Field]
+ field_class: type[pw.Field]
def __init__(self, field: pw.Field, **kwargs):
super(Column, self).__init__(
@@ -132,12 +123,6 @@
"""Generate parameters for self field."""
params = super(Column, self).get_field_parameters()
params.pop("backref", None)
- if change:
- params["unique"] = bool(params.pop("unique", False))
- params["index"] = bool(params.pop("index", False)) or
params["unique"]
- params.pop("on_delete", None)
- params.pop("on_update", None)
- params["null"] = self.nullable
if self.field.default is not None and not callable(self.field.default):
value = self.field.db_value(self.field.default)
@@ -146,119 +131,128 @@
else:
params["default"] = repr(value)
+ if change:
+ params["null"] = self.nullable
+ params["unique"] = bool(params.pop("unique", False))
+ params["index"] = bool(params.pop("index", False)) or
params["unique"]
+
+ params.pop("default", None)
+ params.pop("on_delete", None)
+ params.pop("on_update", None)
+
return params
-def diff_one(model1: TModelType, model2: TModelType, **kwargs) -> List[str]:
# noqa: C901
+def diff_model(model: TModelType, source: TModelType, **opts) -> list[str]:
"""Find difference between given peewee models."""
+ if model._meta.table_name != source._meta.table_name: # type: ignore[]
+ raise ValueError("Cannot diff models with different table names") #
noqa: EM101, TRY003
+
+ return [*diff_model_fields(model, source, **opts),
*diff_model_indexes(model, source)]
+
+
+def diff_model_fields(model: TModelType, source: TModelType, **opts) ->
list[str]:
changes = []
- meta1, meta2 = model1._meta, model2._meta # type: ignore[]
- field_names1 = meta1.fields
- field_names2 = meta2.fields
+ model_fields = {f.name for f in model._meta.sorted_fields} # type:
ignore[]
+ source_fields = {f.name for f in source._meta.sorted_fields} # type:
ignore[]
# Add fields
- names1 = set(field_names1) - set(field_names2)
- if names1:
- fields = [field_names1[name] for name in names1]
- changes.append(create_fields(model1, *fields, **kwargs))
+ fields_to_add = model_fields - source_fields
+ if fields_to_add:
+ fields = list(model_fields_gen(model, *fields_to_add))
+ changes.append(create_fields(model, *fields, **opts))
# Drop fields
- names2 = set(field_names2) - set(field_names1)
- if names2:
- changes.append(drop_fields(model1, *names2))
+ fields_to_remove = source_fields - model_fields
+ if fields_to_remove:
+ fields = list(model_fields_gen(source, *fields_to_remove))
+ changes.append(drop_fields(model, *fields))
# Change fields
- fields_to_change = []
- fields_nulls = []
- fields_indexes = []
- for name in set(field_names1) - names1 - names2:
- field1, field2 = field_names1[name], field_names2[name]
- diff = compare_fields(field1, field2)
- null = diff.pop("null", None)
- index = diff.pop("index", None)
- unique = diff.pop("unique", None)
-
+ fields_to_change = model_fields - fields_to_add - fields_to_remove
+ source_fields_map = source._meta.fields # type: ignore[]
+ for field in model_fields_gen(model, *fields_to_change):
+ source_field = source_fields_map[field.name] # type: ignore[]
+ diff = compare_fields(field, source_field)
if diff:
- fields_to_change.append((field1, diff))
+ changes.append(change_fields(model, (field, diff)))
+ null = diff.pop("null", None)
+ if null is not None:
+ changes.append(change_not_null(model, field.name, null=null))
- if null is not None:
- fields_nulls.append((name, null))
+ return changes
- if (index is not None) or (unique is not None):
- fields_indexes.append((name, index, unique))
- if fields_to_change:
- changes.append(change_fields(model1, *fields_to_change))
-
- for name, null in fields_nulls:
- changes.append(change_not_null(model1, name, null=null))
-
- for name, index, unique in fields_indexes:
- if (index is True) or (unique is True):
- if field_names2[name].unique or field_names2[name].index:
- changes.append(drop_index(model1, name))
- changes.append(add_index(model1, name, unique=unique))
- else:
- changes.append(drop_index(model1, name))
-
- # Check additional compound indexes
- indexes1 = meta1.indexes
- indexes2 = meta2.indexes
+def diff_model_indexes(model: TModelType, source: TModelType) -> list[str]:
+ changes: list[str] = []
- # Drop compound indexes
- indexes_to_drop = set(indexes2) - set(indexes1)
- changes.extend(
- drop_index(model1, name=index[0])
- for index in indexes_to_drop
- if isinstance(index[0], (list, tuple)) and len(index[0]) > 1
- )
+ model_indexes = model._meta.fields_to_index() # type: ignore[]
+ source_indexes = source._meta.fields_to_index() # type: ignore[]
- # Add compound indexes
- indexes_to_add = set(indexes1) - set(indexes2)
- changes.extend(
- add_index(model1, name=index[0], unique=index[1])
- for index in indexes_to_add
- if isinstance(index[0], (list, tuple)) and len(index[0]) > 1
- )
+ model_indexes_names = {idx._name for idx in model_indexes} # type:
ignore[]
+ source_indexes_names = {idx._name for idx in source_indexes} # type:
ignore[]
+
+ # Drop indexes
+ indexes_to_drop = source_indexes_names - model_indexes_names
+ for name in sorted(indexes_to_drop):
+ changes.append( # noqa: PERF401
+ drop_index(next(idx for idx in source_indexes if idx._name ==
name))
+ )
+
+ # Add indexes
+ indexes_to_add = model_indexes_names - source_indexes_names
+ for name in sorted(indexes_to_add):
+ changes.append( # noqa: PERF401
+ add_index(next(idx for idx in model_indexes if idx._name == name))
+ )
+
+ # Change indexes
+ indexes_to_check = model_indexes_names & source_indexes_names
+ for name in sorted(indexes_to_check):
+ idx1 = next(idx for idx in model_indexes if idx._name == name)
+ idx2 = next(idx for idx in source_indexes if idx._name == name)
+ if idx1._unique != idx2._unique or sorted(idx1._expressions) !=
sorted(idx2._expressions):
+ changes.append(drop_index(idx2))
+ changes.append(add_index(idx1))
return changes
def diff_many(
- models1: List[TModelType],
- models2: List[TModelType],
- migrator: Optional[Migrator] = None,
+ active: list[TModelType],
+ source: list[TModelType],
+ migrator: Migrator | None = None,
*,
reverse=False,
-) -> List[str]:
+) -> list[str]:
"""Calculate changes for migrations from models2 to models1."""
- models1 = cast(List["TModelType"], pw.sort_models(models1)) # type:
ignore[]
- models2 = cast(List["TModelType"], pw.sort_models(models2)) # type:
ignore[]
+ active = cast("list[TModelType]", pw.sort_models(active)) # type: ignore[]
+ source = cast("list[TModelType]", pw.sort_models(source)) # type: ignore[]
if reverse:
- models1 = list(reversed(models1))
- models2 = list(reversed(models2))
+ active = list(reversed(active))
+ source = list(reversed(source))
- models_map1 = {cast(str, m._meta.table_name): m for m in models1} # type:
ignore[]
- models_map2 = {cast(str, m._meta.table_name): m for m in models2} # type:
ignore[]
+ active_map = {cast("str", m._meta.table_name): m for m in active} # type:
ignore[]
+ source_map = {cast("str", m._meta.table_name): m for m in source} # type:
ignore[]
- changes: List[str] = []
+ changes: list[str] = []
- for name, model1 in models_map1.items():
- if name not in models_map2:
+ for name, model in active_map.items():
+ if name not in source_map:
continue
- changes.extend(diff_one(model1, models_map2[name], migrator=migrator))
+ changes.extend(diff_model(model, source_map[name], migrator=migrator))
# Add models
changes.extend(
- create_model(models_map1[name], migrator=migrator)
- for name in [m for m in models_map1 if m not in models_map2]
+ create_model(active_map[name], migrator=migrator)
+ for name in [m for m in active_map if m not in source_map]
)
# Remove models
changes.extend(
- remove_model(models_map2[name]) for name in [m for m in models_map2 if
m not in models_map1]
+ remove_model(source_map[name]) for name in [m for m in source_map if m
not in active_map]
)
return changes
@@ -317,13 +311,13 @@
)
-def drop_fields(model_type: TModelType, *fields: pw.Field, **kwargs) -> str:
+def drop_fields(model_type: TModelType, *fields: pw.Field | str) -> str:
"""Generate migrations to remove fields."""
meta = model_type._meta # type: ignore[]
- return "migrator.remove_fields('%s', %s)" % (
- meta.table_name,
- ", ".join(map(repr, fields)),
+ fields = tuple(
+ repr(field.name) if isinstance(field, pw.Field) else repr(field) for
field in fields
)
+ return "migrator.remove_fields('%s', %s)" % (meta.table_name, ",
".join(fields))
def field_to_code(field: pw.Field, *, space: bool = True, **kwargs) -> str:
@@ -332,7 +326,7 @@
return col.get_field(" " if space else "")
-def compare_fields(field1: pw.Field, field2: pw.Field) -> Dict:
+def compare_fields(field1: pw.Field, field2: pw.Field) -> dict:
"""Find diffs between the given fields."""
ftype1, ftype2 = find_field_type(field1), find_field_type(field2)
if ftype1 != ftype2:
@@ -349,7 +343,7 @@
return dict(set(params1.items()) - set(params2.items()))
-def change_fields(model_cls: TModelType, *fields: pw.Tuple[pw.Field, Dict]) ->
str:
+def change_fields(model_cls: TModelType, *fields: pw.Tuple[pw.Field, dict]) ->
str:
"""Generate migrations to change fields."""
meta = model_cls._meta # type: ignore[]
return "migrator.change_fields('%s', %s)" % (
@@ -365,21 +359,24 @@
return "migrator.%s('%s', %s)" % (operation, meta.table_name, repr(name))
-def add_index(model_type: TModelType, name: Union[str, Iterable[str]], *,
unique: bool) -> str:
+def add_index(idx: pw.ModelIndex) -> str:
"""Generate migrations."""
- meta = model_type._meta # type: ignore[]
- columns = repr(name).strip("()[]")
- return f"migrator.add_index('{meta.table_name}', {columns},
unique={unique})"
+ meta = idx._model._meta # type: ignore[]
+ unique = idx._unique # type: ignore[]
+ fields = idx._expressions # type: ignore[]
+ names = ", ".join(f"'{f.name}'" for f in fields)
+ return f"migrator.add_index('{meta.table_name}', {names}, unique={unique})"
-def drop_index(model_type: TModelType, name: Union[str, Iterable[str]]) -> str:
+def drop_index(idx: pw.ModelIndex) -> str:
"""Generate migrations."""
- meta = model_type._meta # type: ignore[]
- columns = repr(name).strip("()[]")
- return f"migrator.drop_index('{meta.table_name}', {columns})"
+ meta = idx._model._meta # type: ignore[]
+ fields = idx._expressions # type: ignore[]
+ names = ", ".join(f"'{f.name}'" for f in fields)
+ return f"migrator.drop_index('{meta.table_name}', {names})"
-def find_field_type(field: pw.Field) -> Type[pw.Field]:
+def find_field_type(field: pw.Field) -> type[pw.Field]:
ftype = type(field)
if ftype.__module__ not in PW_MODULES:
for cls in ftype.mro():
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/peewee_migrate/cli.py
new/peewee_migrate-1.14.3/peewee_migrate/cli.py
--- old/peewee_migrate-1.13.0/peewee_migrate/cli.py 2024-07-17
12:13:20.295652200 +0200
+++ new/peewee_migrate-1.14.3/peewee_migrate/cli.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,11 +1,12 @@
"""CLI integration."""
+
from __future__ import annotations
import logging
import re
import sys
from pathlib import Path
-from typing import TYPE_CHECKING, List, Optional, Pattern, Union
+from typing import TYPE_CHECKING, Pattern
import click
from playhouse.db_url import connect
@@ -17,13 +18,13 @@
if TYPE_CHECKING:
from peewee_migrate.types import TParams
-CLEAN_RE: Pattern = re.compile(r"\s+$", re.M)
-VERBOSE: List[str] = ["WARNING", "INFO", "DEBUG", "NOTSET"]
+CLEAN_RE: Pattern = re.compile(r"\s+$", re.MULTILINE)
+VERBOSE: list[str] = ["WARNING", "INFO", "DEBUG", "NOTSET"]
def get_router(
- directory: Optional[Union[str, Path]] = None,
- database: Optional[str] = None,
+ directory: str | Path | None = None,
+ database: str | None = None,
migratetable: str = MIGRATE_TABLE,
verbose: int = 0,
) -> Router:
@@ -83,9 +84,9 @@
@click.option("--migratetable", default="migratehistory", help="Migration
table.")
@click.option("-v", "--verbose", count=True)
def migrate( # noqa: PLR0913
- name: Optional[str] = None,
- database: Optional[str] = None,
- directory: Optional[str] = None,
+ name: str | None = None,
+ database: str | None = None,
+ directory: str | None = None,
migratetable: str = MIGRATE_TABLE,
verbose: int = 0,
*,
@@ -121,14 +122,14 @@
@click.option("--migratetable", default="migratehistory", help="Migration
table.")
@click.option("-v", "--verbose", count=True)
def create( # noqa: PLR0913
- name: Optional[str] = None,
- database: Optional[str] = None,
- directory: Optional[str] = None,
- migratetable: Optional[str] = None,
+ name: str | None = None,
+ database: str | None = None,
+ directory: str | None = None,
+ migratetable: str | None = None,
verbose: int = 0,
*,
auto: bool = False,
- auto_source: Optional[str] = None,
+ auto_source: str | None = None,
):
"""Create a migration."""
router: Router = get_router(directory, database, migratetable or
MIGRATE_TABLE, verbose)
@@ -148,9 +149,9 @@
@click.option("--migratetable", default="migratehistory", help="Migration
table.")
@click.option("-v", "--verbose", count=True)
def rollback(
- database: Optional[str] = None,
- directory: Optional[str] = None,
- migratetable: Optional[str] = None,
+ database: str | None = None,
+ directory: str | None = None,
+ migratetable: str | None = None,
verbose: int = 0,
count: int = 1,
):
@@ -170,9 +171,9 @@
@click.option("--migratetable", default="migratehistory", help="Migration
table.")
@click.option("-v", "--verbose", count=True)
def list( # noqa: A001
- database: Optional[str] = None,
- directory: Optional[str] = None,
- migratetable: Optional[str] = None,
+ database: str | None = None,
+ directory: str | None = None,
+ migratetable: str | None = None,
verbose: int = 0,
):
"""List migrations."""
@@ -193,9 +194,9 @@
@click.option("--migratetable", default="migratehistory", help="Migration
table.")
@click.option("-v", "--verbose", count=True)
def merge(
- database: Optional[str] = None,
- directory: Optional[str] = None,
- migratetable: Optional[str] = None,
+ database: str | None = None,
+ directory: str | None = None,
+ migratetable: str | None = None,
verbose: int = 0,
):
"""Merge migrations into one."""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/peewee_migrate/migrator.py
new/peewee_migrate-1.14.3/peewee_migrate/migrator.py
--- old/peewee_migrate-1.13.0/peewee_migrate/migrator.py 2024-07-17
12:13:20.295652200 +0200
+++ new/peewee_migrate-1.14.3/peewee_migrate/migrator.py 1970-01-01
01:00:00.000000000 +0100
@@ -3,7 +3,7 @@
from __future__ import annotations
from contextlib import suppress
-from typing import TYPE_CHECKING, Any, Callable, Dict, List, Union, cast,
overload
+from typing import TYPE_CHECKING, Any, Callable, cast, overload
import peewee as pw
from playhouse.migrate import (
@@ -21,8 +21,6 @@
from playhouse.migrate import SchemaMigrator as ScM
from playhouse.migrate import SqliteMigrator as SqM
-from peewee_migrate.utils import depricated_method
-
from .logs import logger
if TYPE_CHECKING:
@@ -30,11 +28,11 @@
class ORM:
- __slots__ = ("__tables__", "__models__")
+ __slots__ = ("__models__", "__tables__")
def __init__(self: ORM):
- self.__tables__: Dict[str, TModelType] = {}
- self.__models__: Dict[str, TModelType] = {}
+ self.__tables__: dict[str, TModelType] = {}
+ self.__models__: dict[str, TModelType] = {}
def add(self, model: TModelType):
self.__models__[model.__name__] = model
@@ -57,7 +55,7 @@
class Migrator:
"""Provide migrations."""
- def __init__(self, database: Union[pw.Database, pw.Proxy]):
+ def __init__(self, database: pw.Database | pw.Proxy):
"""Initialize the migrator."""
self.orm: ORM = ORM()
@@ -65,7 +63,7 @@
database = database.obj
self.__database__ = database
- self.__ops__: List[Union[Operation, Callable]] = []
+ self.__ops__: list[Operation | Callable] = []
self.__migrator__ = SchemaMigrator.from_database(database)
def __call__(self):
@@ -92,14 +90,12 @@
return SyncContext(self)
@overload
- def __get_model__(self, model: TVModelType) -> TVModelType:
- ...
+ def __get_model__(self, model: TVModelType) -> TVModelType: ...
@overload
- def __get_model__(self, model: str) -> TModelType:
- ...
+ def __get_model__(self, model: str) -> TModelType: ...
- def __get_model__(self, model: Union[TVModelType, str]) ->
Union[TVModelType, TModelType]:
+ def __get_model__(self, model: TVModelType | str) -> TVModelType |
TModelType:
"""Get model by name."""
if isinstance(model, str):
if model in self.orm.__models__:
@@ -113,15 +109,13 @@
def sql(self, sql: str, *params):
"""Execute raw SQL."""
- op = cast(Operation, self.__migrator__.sql(sql, *params))
+ op = cast("Operation", self.__migrator__.sql(sql, *params))
self.__ops__.append(op)
def run(self, func: Callable, *args, **kwargs):
"""Run a python function."""
self.__ops__.append(lambda: func(*args, **kwargs))
- python = depricated_method(run, "python")
-
def create_model(self, model: TVModelType) -> TVModelType:
"""Create model and table in database.
@@ -136,9 +130,7 @@
self.__ops__.append(model.create_table)
return model
- create_table = depricated_method(create_model, "create_table")
-
- def remove_model(self, model: Union[str, TModelType], *, cascade: bool =
True):
+ def remove_model(self, model: str | TModelType, *, cascade: bool = True):
"""Drop model and table from database.
:param model: Model class or table name
@@ -150,9 +142,7 @@
self.orm.remove(model)
self.__ops__.append(self.__migrator__.drop_table(model,
cascade=cascade))
- drop_table = depricated_method(remove_model, "drop_table")
-
- def add_fields(self, model: Union[str, TModelType], **fields: pw.Field) ->
TModelType:
+ def add_fields(self, model: str | TModelType, **fields: pw.Field) ->
TModelType:
"""Change fields.
:param model: Model class or table name
@@ -172,9 +162,7 @@
return model
- add_columns = depricated_method(add_fields, "add_columns")
-
- def change_fields(self, model: Union[str, TModelType], **fields: pw.Field)
-> TModelType:
+ def change_fields(self, model: str | TModelType, **fields: pw.Field) ->
TModelType:
"""Change fields.
:param model: Model class or table name
@@ -237,10 +225,8 @@
return model
- change_columns = depricated_method(change_fields, "change_columns")
-
def remove_fields(
- self, model: Union[str, TModelType], *names: str, cascade: bool = True
+ self, model: str | TModelType, *names: str, cascade: bool = True,
**params
) -> TModelType:
"""Remove fields from model.
@@ -257,18 +243,15 @@
if field.unique:
index_name = make_index_name(meta.table_name,
[field.column_name])
self.__ops__.append(self.__migrator__.drop_index(meta.table_name, index_name))
+
self.__ops__.append(
self.__migrator__.drop_column( # type: ignore[]
- meta.table_name, field.column_name, cascade=cascade
+ meta.table_name, field.column_name, cascade=cascade,
**params
)
)
return model
- drop_columns = depricated_method(remove_fields, "drop_columns")
-
- def rename_field(
- self, model: Union[str, TModelType], old_name: str, new_name: str
- ) -> TModelType:
+ def rename_field(self, model: str | TModelType, old_name: str, new_name:
str) -> TModelType:
"""Rename field in model.
:param model: Model class or table name
@@ -292,8 +275,6 @@
)
return model
- rename_column = depricated_method(rename_field, "rename_column")
-
def __del_field__(self, model: TModelType, field: pw.Field):
"""Delete field from model."""
meta = model._meta # type: ignore[]
@@ -307,7 +288,7 @@
delattr(model, obj_id_name)
delattr(field.rel_model, field.backref)
- def rename_table(self, model: Union[str, TModelType], new_name: str) ->
TModelType:
+ def rename_table(self, model: str | TModelType, new_name: str) ->
TModelType:
"""Rename table in database."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
@@ -318,7 +299,9 @@
self.__ops__.append(self.__migrator__.rename_table(old_name, new_name))
return model
- def add_index(self, model: Union[str, TModelType], *columns: str,
unique=False) -> TModelType:
+ def add_index(
+ self, model: str | TModelType, *columns: str, unique=False,
**index_params
+ ) -> TModelType:
"""Create indexes."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
@@ -333,10 +316,12 @@
columns_.append(field.column_name)
- self.__ops__.append(self.__migrator__.add_index(meta.table_name,
columns_, unique=unique))
+ self.__ops__.append(
+ self.__migrator__.add_index(meta.table_name, columns_,
unique=unique, **index_params)
+ )
return model
- def drop_index(self, model: Union[str, TModelType], *columns: str) ->
TModelType:
+ def drop_index(self, model: str | TModelType, *columns: str) -> TModelType:
"""Drop indexes."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
@@ -356,7 +341,7 @@
self.__ops__.append(self.__migrator__.drop_index(meta.table_name,
index_name))
return model
- def add_not_null(self, model: Union[str, TModelType], *names: str) ->
TModelType:
+ def add_not_null(self, model: str | TModelType, *names: str) -> TModelType:
"""Add not null."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
@@ -366,7 +351,7 @@
self.__ops__.append(self.__migrator__.add_not_null(meta.table_name,
field.column_name))
return model
- def drop_not_null(self, model: Union[str, TModelType], *names: str) ->
TModelType:
+ def drop_not_null(self, model: str | TModelType, *names: str) ->
TModelType:
"""Drop not null."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
@@ -376,7 +361,7 @@
self.__ops__.append(self.__migrator__.drop_not_null(meta.table_name,
field.column_name))
return model
- def add_default(self, model: Union[str, TModelType], name: str, default:
Any) -> TModelType:
+ def add_default(self, model: str | TModelType, name: str, default: Any) ->
TModelType:
"""Add default."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
@@ -385,14 +370,14 @@
self.__ops__.append(self.__migrator__.apply_default(meta.table_name,
name, field))
return model
- def add_constraint(self, model: Union[str, TModelType], name, constraint):
+ def add_constraint(self, model: str | TModelType, name, constraint):
"""Add constraint."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
self.__ops__.append(self.__migrator__.add_constraint(meta.table_name,
name, constraint))
return model
- def drop_constraints(self, model: Union[str, TModelType], *names: str) ->
TModelType:
+ def drop_constraints(self, model: str | TModelType, *names: str) ->
TModelType:
"""Drop constraints."""
model = self.__get_model__(model)
meta = model._meta # type: ignore[]
@@ -406,7 +391,7 @@
"""Implement migrations."""
@classmethod
- def from_database(cls, database: Union[pw.Database, pw.Proxy]) ->
SchemaMigrator:
+ def from_database(cls, database: pw.Database | pw.Proxy) ->
SchemaMigrator: # type: ignore[]
"""Initialize migrator by db."""
if isinstance(database, PostgresqlDatabase):
return PostgresqlMigrator(database)
@@ -431,11 +416,9 @@
@operation
def change_column(
self, table: str, column_name: str, field: pw.Field
- ) -> List[Union[Context, Operation]]:
+ ) -> list[Context | Operation]:
"""Change column."""
- operations: List[Union[Context, Operation]] = self.alter_change_column(
- table, column_name, field
- )
+ operations: list[Context | Operation] =
self.alter_change_column(table, column_name, field)
if not field.null:
operations.append(self.add_not_null(table, column_name))
return operations
@@ -449,9 +432,18 @@
ctx: pw.Context = alter_column.literal(" SET DEFAULT ")
return ctx.sql(field.db_value(default))
+ @operation
+ def add_index(self, table, columns, unique=False, using=None,
**index_params): # noqa: FBT002
+ ctx = self.make_context()
+ index_name = make_index_name(table, columns)
+ table_obj = pw.Table(table)
+ cols = [getattr(table_obj.c, column) for column in columns]
+ index = pw.Index(index_name, table_obj, cols, unique=unique,
using=using, **index_params)
+ return ctx.sql(index)
+
def alter_change_column(
self, table: str, column: str, field: pw.Field
- ) -> List[Union[Context, Operation]]:
+ ) -> list[Context | Operation]:
"""Support change columns."""
ctx = self.make_context()
field_null, field.null = field.null, True
@@ -475,7 +467,7 @@
def alter_change_column(
self, table: str, column: str, field: pw.Field
- ) -> List[Union[Context, Operation]]:
+ ) -> list[Context | Operation]:
"""Support change columns."""
ctx = self.make_context()
field_null, field.null = field.null, True
@@ -489,7 +481,7 @@
def alter_change_column(
self, table: str, column: str, field: pw.Field
- ) -> List[Union[Context, Operation]]:
+ ) -> list[Context | Operation]:
"""Support change columns."""
ctx = self.make_context()
fn, field.null = field.null, True
@@ -507,13 +499,13 @@
class SqliteMigrator(SchemaMigrator, SqM):
"""Support the migrations in sqlite."""
- def drop_table(self, model: pw.Model, *, cascade: bool = True) -> Callable:
+ def drop_table(self, model: TModelType, *, cascade: bool = True) ->
Callable:
"""Sqlite doesnt support cascade syntax by default."""
return lambda: model.drop_table(cascade=False)
def alter_change_column(
self, table: str, column: str, field: pw.Field
- ) -> List[Union[Operation, Context]]:
+ ) -> list[Operation | Context]:
"""Support change columns."""
def fn(c_name, c_def):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/peewee_migrate/models.py
new/peewee_migrate-1.14.3/peewee_migrate/models.py
--- old/peewee_migrate-1.13.0/peewee_migrate/models.py 2024-07-17
12:13:20.295652200 +0200
+++ new/peewee_migrate-1.14.3/peewee_migrate/models.py 1970-01-01
01:00:00.000000000 +0100
@@ -9,7 +9,7 @@
class MigrateHistory(pw.Model):
"""Presents the migrations in database."""
- id = pw.AutoField() # noqa: A003
+ id = pw.AutoField()
name = pw.CharField()
migrated_at = pw.DateTimeField(default=dt.datetime.utcnow)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/peewee_migrate/router.py
new/peewee_migrate-1.14.3/peewee_migrate/router.py
--- old/peewee_migrate-1.13.0/peewee_migrate/router.py 2024-07-17
12:13:20.295652200 +0200
+++ new/peewee_migrate-1.14.3/peewee_migrate/router.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,7 +1,7 @@
"""Migration router."""
+
from __future__ import annotations
-import os
import pkgutil
import re
import sys
@@ -9,7 +9,7 @@
from importlib import import_module
from pathlib import Path
from types import ModuleType
-from typing import TYPE_CHECKING, Any, Final, Iterable, List, Optional, Set,
Type, Union
+from typing import TYPE_CHECKING, Any, Final, Iterable
from unittest import mock
import peewee as pw
@@ -26,7 +26,7 @@
from peewee_migrate.types import TModelType
-CLEAN_RE: Final = re.compile(r"\s+$", re.M)
+CLEAN_RE: Final = re.compile(r"\s+$", re.MULTILINE)
CURDIR: Final = Path.cwd()
DEFAULT_MIGRATE_DIR: Final = CURDIR / "migrations"
@@ -40,12 +40,12 @@
def __init__( # noqa: PLR0913
self,
- database: Union[pw.Database, pw.Proxy],
+ database: pw.Database | pw.Proxy,
migrate_table=MIGRATE_TABLE,
- ignore: Optional[Iterable[str]] = None,
- schema: Optional[str] = None,
+ ignore: Iterable[str] | None = None,
+ schema: str | None = None,
logger: Logger = logger,
- migrator_class: Type[Migrator] = Migrator,
+ migrator_class: type[Migrator] = Migrator,
):
"""Initialize the router."""
self.database = database
@@ -60,7 +60,7 @@
raise TypeError("Invalid migrator_class: %s" % database)
@cached_property
- def model(self) -> Type[MigrateHistory]:
+ def model(self) -> type[MigrateHistory]:
"""Initialize and cache MigrationHistory model."""
meta = MigrateHistory._meta # type: ignore[]
meta.database = self.database
@@ -75,12 +75,12 @@
raise NotImplementedError
@property
- def done(self) -> List[str]:
+ def done(self) -> list[str]:
"""Scan migrations in database."""
return [mm.name for mm in self.model.select().order_by(self.model.id)]
@property
- def diff(self) -> List[str]:
+ def diff(self) -> list[str]:
"""Calculate difference between fs and db."""
done = set(self.done)
return [name for name in self.todo if name not in done]
@@ -93,7 +93,7 @@
self.run_one(name, migrator)
return migrator
- def create(self, name: str = "auto", *, auto: Any = False) ->
Optional[str]:
+ def create(self, name: str = "auto", *, auto: Any = False) -> str | None:
"""Create a migration.
:param auto: Python module path to scan for models.
@@ -156,8 +156,8 @@
"""Clear migrations."""
self.model.delete().execute()
- def compile( # noqa: A003
- self, name: str, migrate: str = "", rollback: str = "", num:
Optional[int] = None
+ def compile(
+ self, name: str, migrate: str = "", rollback: str = "", num: int |
None = None
) -> str:
"""Create a migration."""
raise NotImplementedError
@@ -166,7 +166,7 @@
"""Read migration from file."""
raise NotImplementedError
- def run_one( # noqa: PLR0913
+ def run_one(
self,
name: str,
migrator: Migrator,
@@ -181,8 +181,9 @@
if fake:
mocked_cursor = mock.Mock()
mocked_cursor.fetch_one.return_value = None
- with mock.patch("peewee.Model.select"), mock.patch(
- "peewee.Database.execute_sql", return_value=mocked_cursor
+ with (
+ mock.patch("peewee.Model.select"),
+ mock.patch("peewee.Database.execute_sql",
return_value=mocked_cursor),
):
migrate(migrator, self.database, fake=fake)
@@ -214,11 +215,11 @@
self.logger.exception("%s failed: %s", operation, name)
raise
- def run(self, name: Optional[str] = None, *, fake: bool = False) ->
List[str]:
+ def run(self, name: str | None = None, *, fake: bool = False) -> list[str]:
"""Run migrations."""
self.logger.info("Starting migrations")
- done: List[str] = []
+ done: list[str] = []
diff = self.diff
if not diff:
self.logger.info("There is nothing to migrate")
@@ -253,7 +254,7 @@
def __init__(
self,
database,
- migrate_dir: Optional[Union[str, Path]] = None,
+ migrate_dir: str | Path | None = None,
**kwargs,
):
"""Initialize the router."""
@@ -270,9 +271,9 @@
if not self.migrate_dir.exists():
self.logger.warning("Migration directory: %s does not exist.",
self.migrate_dir)
self.migrate_dir.mkdir(parents=True)
- return sorted(f[:-3] for f in os.listdir(self.migrate_dir) if
self.filemask.match(f))
+ return sorted(f.stem for f in Path.iterdir(self.migrate_dir) if
self.filemask.match(f.name))
- def compile(self, name, migrate="", rollback="", num=None) -> str: #
noqa: A003
+ def compile(self, name, migrate="", rollback="", num=None) -> str:
"""Create a migration."""
if num is None:
num = len(self.todo)
@@ -321,7 +322,7 @@
return getattr(mod, "migrate", void), getattr(mod, "rollback", void)
-def load_models(module: Union[str, ModuleType]) -> Set[Type[pw.Model]]:
+def load_models(module: str | ModuleType) -> set[TModelType]:
"""Load models from given module."""
modules = [module] if isinstance(module, ModuleType) else
_import_submodules(module)
@@ -332,31 +333,36 @@
}
-def _import_submodules(package, passed=...):
- if passed is ...:
+def _import_submodules(
+ package: str | ModuleType, passed: set[str] | None = None
+) -> list[ModuleType]:
+ if passed is None:
passed = set()
if isinstance(package, str):
package = import_module(package)
- # https://github.com/klen/peewee_migrate/issues/125
if not hasattr(package, "__path__"):
- return {package}
+ return [package]
- modules = []
- if set(package.__path__) & passed:
- return modules
+ path_ids = set(map(str, package.__path__))
+ if passed & path_ids:
+ return []
+ passed |= path_ids
- passed |= set(package.__path__)
+ modules: list[ModuleType] = [package]
+ prefix = package.__name__ + "."
- for loader, name, is_pkg in pkgutil.walk_packages(package.__path__,
package.__name__ + "."):
- spec = loader.find_spec(name, None)
- if spec is None or spec.loader is None:
+ for _finder, name, is_pkg in pkgutil.walk_packages(package.__path__,
prefix):
+ try:
+ module = import_module(name)
+ except ImportError:
continue
- module = spec.loader.load_module(name)
+
modules.append(module)
if is_pkg:
- modules += _import_submodules(module)
+ modules.extend(_import_submodules(module, passed))
+
return modules
@@ -365,7 +371,7 @@
return isinstance(obj, type) and issubclass(obj, pw.Model) and
hasattr(obj, "_meta")
-def compile_migrations(migrator: Migrator, models: List[TModelType], *,
reverse=False) -> str:
+def compile_migrations(migrator: Migrator, models: list[TModelType], *,
reverse=False) -> str:
"""Compile migrations for given models."""
source = list(migrator.orm)
if reverse:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/peewee_migrate/types.py
new/peewee_migrate-1.14.3/peewee_migrate/types.py
--- old/peewee_migrate-1.13.0/peewee_migrate/types.py 2024-07-17
12:13:20.295652200 +0200
+++ new/peewee_migrate-1.14.3/peewee_migrate/types.py 1970-01-01
01:00:00.000000000 +0100
@@ -2,11 +2,11 @@
from __future__ import annotations
-from typing import Any, Dict, Type, TypeVar
+from typing import Any, TypeVar
from peewee import Model
-TModelType = Type[Model]
-TParams = Dict[str, Any]
+TModelType = type[Model]
+TParams = dict[str, Any]
TVModelType = TypeVar("TVModelType", bound=TModelType)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/peewee_migrate/utils.py
new/peewee_migrate-1.14.3/peewee_migrate/utils.py
--- old/peewee_migrate-1.13.0/peewee_migrate/utils.py 2024-07-17
12:13:20.295652200 +0200
+++ new/peewee_migrate-1.14.3/peewee_migrate/utils.py 1970-01-01
01:00:00.000000000 +0100
@@ -1,13 +1,17 @@
-from warnings import warn
+from peewee_migrate.types import TModelType
-def depricated_method(fn, depricated_fn_name):
- def wrapper(*args, **kwargs):
- warn(
- f"{depricated_fn_name} is depricated. Use {fn.__name__} instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- return fn(*args, **kwargs)
+def model_fields_gen(model: TModelType, *names: str):
+ """Get model fields by names.
- return wrapper
+ Args:
+ model (pw.Model): Peewee model.
+ *names (str): Field names.
+
+ Returns:
+ list: List of fields.
+ """
+ meta = model._meta # type: ignore[]
+ for field in meta.sorted_fields:
+ if field.name in names:
+ yield field
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/peewee_migrate-1.13.0/pyproject.toml
new/peewee_migrate-1.14.3/pyproject.toml
--- old/peewee_migrate-1.13.0/pyproject.toml 2024-07-17 12:13:20.295652200
+0200
+++ new/peewee_migrate-1.14.3/pyproject.toml 1970-01-01 01:00:00.000000000
+0100
@@ -1,6 +1,6 @@
[tool.poetry]
name = "peewee-migrate"
-version = "1.13.0"
+version = "1.14.3"
homepage = "https://github.com/klen/peewee_migrate"
repository = "https://github.com/klen/peewee_migrate"
description = "Support for migrations in Peewee ORM"
@@ -14,11 +14,11 @@
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
+ "Programming Language :: Python :: 3.14",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Utilities",
]
@@ -28,7 +28,7 @@
pw-migrate = "peewee_migrate.cli:cli"
[tool.poetry.dependencies]
-python = "^3.8"
+python = "^3.10"
peewee = "^3"
click = "*"
@@ -42,7 +42,7 @@
[tool.ruff]
line-length = 100
-target-version = "py38"
+target-version = "py310"
select = ["ALL"]
ignore = ["ANN", "ARG", "COM", "D", "N", "UP", "S", "SLF", "INP001", "PLR2004"]
@@ -55,7 +55,7 @@
[tool.black]
line-length = 100
-target-version = ["py38", "py39", "py310", "py311"]
+target-version = ["py310"]
preview = true
[build-system]