Merge pull request #60 from tortoise/refactoring
Refactoring migrate logic
This commit is contained in:
commit
1bf6d45bb0
12
CHANGELOG.md
12
CHANGELOG.md
@ -1,5 +1,17 @@
|
|||||||
# ChangeLog
|
# ChangeLog
|
||||||
|
|
||||||
|
## 0.3
|
||||||
|
|
||||||
|
### 0.3.0
|
||||||
|
|
||||||
|
- Refactoring migrate logic, and this version is not compatible with previous version.
|
||||||
|
- Now there don't need `old_models.py` and it store in database.
|
||||||
|
- Upgrade steps:
|
||||||
|
1. Upgrade aerich version.
|
||||||
|
2. Drop aerich model in db and recreate with new struct.
|
||||||
|
3. Delete `migrations/{app}` folder and rerun `aerich init-db`.
|
||||||
|
4. Update model and `aerich migrate` normally.
|
||||||
|
|
||||||
## 0.2
|
## 0.2
|
||||||
|
|
||||||
### 0.2.5
|
### 0.2.5
|
||||||
|
16
README.md
16
README.md
@ -125,7 +125,19 @@ Success upgrade 1_202029051520102929_drop_column.json
|
|||||||
|
|
||||||
Now your db is migrated to latest.
|
Now your db is migrated to latest.
|
||||||
|
|
||||||
### Downgrade to previous version
|
### Downgrade to specified version
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$ aerich init -h
|
||||||
|
|
||||||
|
Usage: aerich downgrade [OPTIONS]
|
||||||
|
|
||||||
|
Downgrade to specified version.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-v, --version INTEGER Specified version, default to last. [default: -1]
|
||||||
|
-h, --help Show this message and exit.
|
||||||
|
```
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ aerich downgrade
|
$ aerich downgrade
|
||||||
@ -133,7 +145,7 @@ $ aerich downgrade
|
|||||||
Success downgrade 1_202029051520102929_drop_column.json
|
Success downgrade 1_202029051520102929_drop_column.json
|
||||||
```
|
```
|
||||||
|
|
||||||
Now your db rollback to previous version.
|
Now your db rollback to specified version.
|
||||||
|
|
||||||
### Show history
|
### Show history
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
__version__ = "0.2.5"
|
__version__ = "0.3.0"
|
||||||
|
@ -26,7 +26,9 @@ def coro(f):
|
|||||||
@wraps(f)
|
@wraps(f)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
loop = asyncio.get_event_loop()
|
loop = asyncio.get_event_loop()
|
||||||
return loop.run_until_complete(f(*args, **kwargs))
|
ctx = args[0]
|
||||||
|
loop.run_until_complete(f(*args, **kwargs))
|
||||||
|
Migrate.remove_old_model_file(ctx.obj["app"], ctx.obj["location"])
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
@ -67,7 +69,7 @@ async def cli(ctx: Context, config, app, name):
|
|||||||
ctx.obj["config"] = tortoise_config
|
ctx.obj["config"] = tortoise_config
|
||||||
ctx.obj["location"] = location
|
ctx.obj["location"] = location
|
||||||
ctx.obj["app"] = app
|
ctx.obj["app"] = app
|
||||||
|
Migrate.app = app
|
||||||
if invoked_subcommand != "init-db":
|
if invoked_subcommand != "init-db":
|
||||||
await Migrate.init_with_old_models(tortoise_config, app, location)
|
await Migrate.init_with_old_models(tortoise_config, app, location)
|
||||||
|
|
||||||
@ -77,64 +79,82 @@ async def cli(ctx: Context, config, app, name):
|
|||||||
@click.pass_context
|
@click.pass_context
|
||||||
@coro
|
@coro
|
||||||
async def migrate(ctx: Context, name):
|
async def migrate(ctx: Context, name):
|
||||||
config = ctx.obj["config"]
|
|
||||||
location = ctx.obj["location"]
|
|
||||||
app = ctx.obj["app"]
|
|
||||||
ret = await Migrate.migrate(name)
|
ret = await Migrate.migrate(name)
|
||||||
if not ret:
|
if not ret:
|
||||||
return click.secho("No changes detected", fg=Color.yellow)
|
return click.secho("No changes detected", fg=Color.yellow)
|
||||||
Migrate.write_old_models(config, app, location)
|
|
||||||
click.secho(f"Success migrate {ret}", fg=Color.green)
|
click.secho(f"Success migrate {ret}", fg=Color.green)
|
||||||
|
|
||||||
|
|
||||||
@cli.command(help="Upgrade to latest version.")
|
@cli.command(help="Upgrade to specified version.")
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
@coro
|
@coro
|
||||||
async def upgrade(ctx: Context):
|
async def upgrade(ctx: Context):
|
||||||
config = ctx.obj["config"]
|
config = ctx.obj["config"]
|
||||||
app = ctx.obj["app"]
|
app = ctx.obj["app"]
|
||||||
|
location = ctx.obj["location"]
|
||||||
migrated = False
|
migrated = False
|
||||||
for version in Migrate.get_all_version_files():
|
for version_file in Migrate.get_all_version_files():
|
||||||
try:
|
try:
|
||||||
exists = await Aerich.exists(version=version, app=app)
|
exists = await Aerich.exists(version=version_file, app=app)
|
||||||
except OperationalError:
|
except OperationalError:
|
||||||
exists = False
|
exists = False
|
||||||
if not exists:
|
if not exists:
|
||||||
async with in_transaction(get_app_connection_name(config, app)) as conn:
|
async with in_transaction(get_app_connection_name(config, app)) as conn:
|
||||||
file_path = os.path.join(Migrate.migrate_location, version)
|
file_path = os.path.join(Migrate.migrate_location, version_file)
|
||||||
with open(file_path, "r", encoding="utf-8") as f:
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
content = json.load(f)
|
content = json.load(f)
|
||||||
upgrade_query_list = content.get("upgrade")
|
upgrade_query_list = content.get("upgrade")
|
||||||
for upgrade_query in upgrade_query_list:
|
for upgrade_query in upgrade_query_list:
|
||||||
await conn.execute_script(upgrade_query)
|
await conn.execute_script(upgrade_query)
|
||||||
await Aerich.create(version=version, app=app)
|
await Aerich.create(
|
||||||
click.secho(f"Success upgrade {version}", fg=Color.green)
|
version=version_file,
|
||||||
|
app=app,
|
||||||
|
content=Migrate.get_models_content(config, app, location),
|
||||||
|
)
|
||||||
|
click.secho(f"Success upgrade {version_file}", fg=Color.green)
|
||||||
migrated = True
|
migrated = True
|
||||||
if not migrated:
|
if not migrated:
|
||||||
click.secho("No migrate items", fg=Color.yellow)
|
click.secho("No migrate items", fg=Color.yellow)
|
||||||
|
|
||||||
|
|
||||||
@cli.command(help="Downgrade to previous version.")
|
@cli.command(help="Downgrade to specified version.")
|
||||||
|
@click.option(
|
||||||
|
"-v",
|
||||||
|
"--version",
|
||||||
|
default=-1,
|
||||||
|
type=int,
|
||||||
|
show_default=True,
|
||||||
|
help="Specified version, default to last.",
|
||||||
|
)
|
||||||
@click.pass_context
|
@click.pass_context
|
||||||
@coro
|
@coro
|
||||||
async def downgrade(ctx: Context):
|
async def downgrade(ctx: Context, version: int):
|
||||||
app = ctx.obj["app"]
|
app = ctx.obj["app"]
|
||||||
config = ctx.obj["config"]
|
config = ctx.obj["config"]
|
||||||
last_version = await Migrate.get_last_version()
|
if version == -1:
|
||||||
if not last_version:
|
specified_version = await Migrate.get_last_version()
|
||||||
return click.secho("No last version found", fg=Color.yellow)
|
else:
|
||||||
file = last_version.version
|
specified_version = await Aerich.filter(app=app, version__startswith=f"{version}_").first()
|
||||||
async with in_transaction(get_app_connection_name(config, app)) as conn:
|
if not specified_version:
|
||||||
file_path = os.path.join(Migrate.migrate_location, file)
|
return click.secho("No specified version found", fg=Color.yellow)
|
||||||
with open(file_path, "r", encoding="utf-8") as f:
|
if version == -1:
|
||||||
content = json.load(f)
|
versions = [specified_version]
|
||||||
downgrade_query_list = content.get("downgrade")
|
else:
|
||||||
if not downgrade_query_list:
|
versions = await Aerich.filter(app=app, pk__gte=specified_version.pk)
|
||||||
return click.secho("No downgrade item found", fg=Color.yellow)
|
for version in versions:
|
||||||
for downgrade_query in downgrade_query_list:
|
file = version.version
|
||||||
await conn.execute_query(downgrade_query)
|
async with in_transaction(get_app_connection_name(config, app)) as conn:
|
||||||
await last_version.delete()
|
file_path = os.path.join(Migrate.migrate_location, file)
|
||||||
return click.secho(f"Success downgrade {file}", fg=Color.green)
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
|
content = json.load(f)
|
||||||
|
downgrade_query_list = content.get("downgrade")
|
||||||
|
if not downgrade_query_list:
|
||||||
|
return click.secho("No downgrade item found", fg=Color.yellow)
|
||||||
|
for downgrade_query in downgrade_query_list:
|
||||||
|
await conn.execute_query(downgrade_query)
|
||||||
|
await version.delete()
|
||||||
|
os.unlink(file_path)
|
||||||
|
click.secho(f"Success downgrade {file}", fg=Color.green)
|
||||||
|
|
||||||
|
|
||||||
@cli.command(help="Show current available heads in migrate location.")
|
@cli.command(help="Show current available heads in migrate location.")
|
||||||
@ -149,7 +169,7 @@ async def heads(ctx: Context):
|
|||||||
click.secho(version, fg=Color.green)
|
click.secho(version, fg=Color.green)
|
||||||
is_heads = True
|
is_heads = True
|
||||||
if not is_heads:
|
if not is_heads:
|
||||||
click.secho("No available heads,try migrate", fg=Color.green)
|
click.secho("No available heads,try migrate first", fg=Color.green)
|
||||||
|
|
||||||
|
|
||||||
@cli.command(help="List all migrate items.")
|
@cli.command(help="List all migrate items.")
|
||||||
@ -219,8 +239,6 @@ async def init_db(ctx: Context, safe):
|
|||||||
else:
|
else:
|
||||||
return click.secho(f"Inited {app} already", fg=Color.yellow)
|
return click.secho(f"Inited {app} already", fg=Color.yellow)
|
||||||
|
|
||||||
Migrate.write_old_models(config, app, location)
|
|
||||||
|
|
||||||
await Tortoise.init(config=config)
|
await Tortoise.init(config=config)
|
||||||
connection = get_app_connection(config, app)
|
connection = get_app_connection(config, app)
|
||||||
await generate_schema_for_client(connection, safe)
|
await generate_schema_for_client(connection, safe)
|
||||||
@ -228,7 +246,9 @@ async def init_db(ctx: Context, safe):
|
|||||||
schema = get_schema_sql(connection, safe)
|
schema = get_schema_sql(connection, safe)
|
||||||
|
|
||||||
version = await Migrate.generate_version()
|
version = await Migrate.generate_version()
|
||||||
await Aerich.create(version=version, app=app)
|
await Aerich.create(
|
||||||
|
version=version, app=app, content=Migrate.get_models_content(config, app, location)
|
||||||
|
)
|
||||||
with open(os.path.join(dirname, version), "w", encoding="utf-8") as f:
|
with open(os.path.join(dirname, version), "w", encoding="utf-8") as f:
|
||||||
content = {
|
content = {
|
||||||
"upgrade": [schema],
|
"upgrade": [schema],
|
||||||
|
@ -13,7 +13,7 @@ class SqliteDDL(BaseDDL):
|
|||||||
DIALECT = SqliteSchemaGenerator.DIALECT
|
DIALECT = SqliteSchemaGenerator.DIALECT
|
||||||
|
|
||||||
def drop_column(self, model: "Type[Model]", column_name: str):
|
def drop_column(self, model: "Type[Model]", column_name: str):
|
||||||
raise NotSupportError("Drop column is not support in SQLite.")
|
raise NotSupportError("Drop column is unsupported in SQLite.")
|
||||||
|
|
||||||
def modify_column(self, model: "Type[Model]", field_object: Field):
|
def modify_column(self, model: "Type[Model]", field_object: Field):
|
||||||
raise NotSupportError("Modify column is not support in SQLite.")
|
raise NotSupportError("Modify column is unsupported in SQLite.")
|
||||||
|
@ -3,6 +3,7 @@ import os
|
|||||||
import re
|
import re
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
|
from io import StringIO
|
||||||
from typing import Dict, List, Tuple, Type
|
from typing import Dict, List, Tuple, Type
|
||||||
|
|
||||||
import click
|
import click
|
||||||
@ -41,8 +42,8 @@ class Migrate:
|
|||||||
dialect: str
|
dialect: str
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_old_model_file(cls):
|
def get_old_model_file(cls, app: str, location: str):
|
||||||
return cls.old_models + ".py"
|
return os.path.join(location, app, cls.old_models + ".py")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_all_version_files(cls) -> List[str]:
|
def get_all_version_files(cls) -> List[str]:
|
||||||
@ -56,9 +57,21 @@ class Migrate:
|
|||||||
return await Aerich.filter(app=cls.app).first()
|
return await Aerich.filter(app=cls.app).first()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
async def init_with_old_models(cls, config: dict, app: str, location: str):
|
def remove_old_model_file(cls, app: str, location: str):
|
||||||
migrate_config = cls._get_migrate_config(config, app, location)
|
try:
|
||||||
|
os.unlink(cls.get_old_model_file(app, location))
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
async def init_with_old_models(cls, config: dict, app: str, location: str):
|
||||||
|
await Tortoise.init(config=config)
|
||||||
|
last_version = await cls.get_last_version()
|
||||||
|
content = last_version.content
|
||||||
|
with open(cls.get_old_model_file(app, location), "w") as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
migrate_config = cls._get_migrate_config(config, app, location)
|
||||||
cls.app = app
|
cls.app = app
|
||||||
cls.migrate_config = migrate_config
|
cls.migrate_config = migrate_config
|
||||||
cls.migrate_location = os.path.join(location, app)
|
cls.migrate_location = os.path.join(location, app)
|
||||||
@ -102,6 +115,10 @@ class Migrate:
|
|||||||
@classmethod
|
@classmethod
|
||||||
async def _generate_diff_sql(cls, name):
|
async def _generate_diff_sql(cls, name):
|
||||||
version = await cls.generate_version(name)
|
version = await cls.generate_version(name)
|
||||||
|
# delete if same version exists
|
||||||
|
for version_file in cls.get_all_version_files():
|
||||||
|
if version_file.startswith(version.split("_")[0]):
|
||||||
|
os.unlink(os.path.join(cls.migrate_location, version_file))
|
||||||
content = {
|
content = {
|
||||||
"upgrade": cls.upgrade_operators,
|
"upgrade": cls.upgrade_operators,
|
||||||
"downgrade": cls.downgrade_operators,
|
"downgrade": cls.downgrade_operators,
|
||||||
@ -151,26 +168,6 @@ class Migrate:
|
|||||||
else:
|
else:
|
||||||
cls.downgrade_operators.append(operator)
|
cls.downgrade_operators.append(operator)
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def cp_models(
|
|
||||||
cls, app: str, model_files: List[str], old_model_file,
|
|
||||||
):
|
|
||||||
"""
|
|
||||||
cp currents models to old_model_files
|
|
||||||
:param app:
|
|
||||||
:param model_files:
|
|
||||||
:param old_model_file:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
pattern = rf"(\n)?('|\")({app})(.\w+)('|\")"
|
|
||||||
for i, model_file in enumerate(model_files):
|
|
||||||
with open(model_file, "r", encoding="utf-8") as f:
|
|
||||||
content = f.read()
|
|
||||||
ret = re.sub(pattern, rf"\2{cls.diff_app}\4\5", content)
|
|
||||||
mode = "w" if i == 0 else "a"
|
|
||||||
with open(old_model_file, mode, encoding="utf-8") as f:
|
|
||||||
f.write(f"{ret}\n")
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_migrate_config(cls, config: dict, app: str, location: str):
|
def _get_migrate_config(cls, config: dict, app: str, location: str):
|
||||||
"""
|
"""
|
||||||
@ -189,7 +186,7 @@ class Migrate:
|
|||||||
return config
|
return config
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def write_old_models(cls, config: dict, app: str, location: str):
|
def get_models_content(cls, config: dict, app: str, location: str):
|
||||||
"""
|
"""
|
||||||
write new models to old models
|
write new models to old models
|
||||||
:param config:
|
:param config:
|
||||||
@ -197,14 +194,18 @@ class Migrate:
|
|||||||
:param location:
|
:param location:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
cls.app = app
|
|
||||||
|
|
||||||
old_model_files = []
|
old_model_files = []
|
||||||
models = config.get("apps").get(app).get("models")
|
models = config.get("apps").get(app).get("models")
|
||||||
for model in models:
|
for model in models:
|
||||||
old_model_files.append(import_module(model).__file__)
|
old_model_files.append(import_module(model).__file__)
|
||||||
|
pattern = rf"(\n)?('|\")({app})(.\w+)('|\")"
|
||||||
cls.cp_models(app, old_model_files, os.path.join(location, app, cls.get_old_model_file()))
|
str_io = StringIO()
|
||||||
|
for i, model_file in enumerate(old_model_files):
|
||||||
|
with open(model_file, "r", encoding="utf-8") as f:
|
||||||
|
content = f.read()
|
||||||
|
ret = re.sub(pattern, rf"\2{cls.diff_app}\4\5", content)
|
||||||
|
str_io.write(f"{ret}\n")
|
||||||
|
return str_io.getvalue()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def diff_models(
|
def diff_models(
|
||||||
|
@ -6,6 +6,7 @@ MAX_VERSION_LENGTH = 255
|
|||||||
class Aerich(Model):
|
class Aerich(Model):
|
||||||
version = fields.CharField(max_length=MAX_VERSION_LENGTH)
|
version = fields.CharField(max_length=MAX_VERSION_LENGTH)
|
||||||
app = fields.CharField(max_length=20)
|
app = fields.CharField(max_length=20)
|
||||||
|
content = fields.TextField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ["-id"]
|
ordering = ["-id"]
|
||||||
|
97
poetry.lock
generated
97
poetry.lock
generated
@ -177,7 +177,7 @@ description = "the modular source code checker: pep8 pyflakes and co"
|
|||||||
name = "flake8"
|
name = "flake8"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
|
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7"
|
||||||
version = "3.8.3"
|
version = "3.8.4"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
mccabe = ">=0.6.0,<0.7.0"
|
mccabe = ">=0.6.0,<0.7.0"
|
||||||
@ -205,7 +205,7 @@ description = "Python Git Library"
|
|||||||
name = "gitpython"
|
name = "gitpython"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.4"
|
python-versions = ">=3.4"
|
||||||
version = "3.1.8"
|
version = "3.1.9"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
gitdb = ">=4.0.1,<5"
|
gitdb = ">=4.0.1,<5"
|
||||||
@ -248,7 +248,7 @@ description = "A Python utility / library to sort Python imports."
|
|||||||
name = "isort"
|
name = "isort"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6,<4.0"
|
python-versions = ">=3.6,<4.0"
|
||||||
version = "5.5.3"
|
version = "5.6.1"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
colors = ["colorama (>=0.4.3,<0.5.0)"]
|
colors = ["colorama (>=0.4.3,<0.5.0)"]
|
||||||
@ -263,14 +263,6 @@ optional = false
|
|||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.6.1"
|
version = "0.6.1"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
category = "dev"
|
|
||||||
description = "More routines for operating on iterables, beyond itertools"
|
|
||||||
name = "more-itertools"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.5"
|
|
||||||
version = "8.5.0"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
description = "Core utilities for Python packages"
|
description = "Core utilities for Python packages"
|
||||||
@ -385,7 +377,7 @@ description = "A SQL query builder API for Python"
|
|||||||
name = "pypika"
|
name = "pypika"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "0.40.0"
|
version = "0.42.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "dev"
|
category = "dev"
|
||||||
@ -393,14 +385,13 @@ description = "pytest: simple powerful testing with Python"
|
|||||||
name = "pytest"
|
name = "pytest"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
version = "6.0.2"
|
version = "6.1.1"
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
atomicwrites = ">=1.0"
|
atomicwrites = ">=1.0"
|
||||||
attrs = ">=17.4.0"
|
attrs = ">=17.4.0"
|
||||||
colorama = "*"
|
colorama = "*"
|
||||||
iniconfig = "*"
|
iniconfig = "*"
|
||||||
more-itertools = ">=4.0.0"
|
|
||||||
packaging = "*"
|
packaging = "*"
|
||||||
pluggy = ">=0.12,<1.0"
|
pluggy = ">=0.12,<1.0"
|
||||||
py = ">=1.8.2"
|
py = ">=1.8.2"
|
||||||
@ -485,7 +476,7 @@ description = "Alternative regular expression module, to replace re."
|
|||||||
name = "regex"
|
name = "regex"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
version = "2020.7.14"
|
version = "2020.9.27"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
category = "main"
|
category = "main"
|
||||||
@ -566,7 +557,7 @@ marker = "python_version < \"3.8\""
|
|||||||
name = "zipp"
|
name = "zipp"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
version = "3.2.0"
|
version = "3.3.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
docs = ["sphinx", "jaraco.packaging (>=3.2)", "rst.linker (>=1.9)"]
|
||||||
@ -577,7 +568,6 @@ dbdrivers = ["aiomysql", "asyncpg"]
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
content-hash = "43fe9c0036f4d55d38f82c263887d8a7d9a35a597e02036b70a631955ff73149"
|
content-hash = "43fe9c0036f4d55d38f82c263887d8a7d9a35a597e02036b70a631955ff73149"
|
||||||
lock-version = "1.0"
|
|
||||||
python-versions = "^3.7"
|
python-versions = "^3.7"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
@ -715,16 +705,16 @@ execnet = [
|
|||||||
{file = "execnet-1.7.1.tar.gz", hash = "sha256:cacb9df31c9680ec5f95553976c4da484d407e85e41c83cb812aa014f0eddc50"},
|
{file = "execnet-1.7.1.tar.gz", hash = "sha256:cacb9df31c9680ec5f95553976c4da484d407e85e41c83cb812aa014f0eddc50"},
|
||||||
]
|
]
|
||||||
flake8 = [
|
flake8 = [
|
||||||
{file = "flake8-3.8.3-py2.py3-none-any.whl", hash = "sha256:15e351d19611c887e482fb960eae4d44845013cc142d42896e9862f775d8cf5c"},
|
{file = "flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"},
|
||||||
{file = "flake8-3.8.3.tar.gz", hash = "sha256:f04b9fcbac03b0a3e58c0ab3a0ecc462e023a9faf046d57794184028123aa208"},
|
{file = "flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"},
|
||||||
]
|
]
|
||||||
gitdb = [
|
gitdb = [
|
||||||
{file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"},
|
{file = "gitdb-4.0.5-py3-none-any.whl", hash = "sha256:91f36bfb1ab7949b3b40e23736db18231bf7593edada2ba5c3a174a7b23657ac"},
|
||||||
{file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"},
|
{file = "gitdb-4.0.5.tar.gz", hash = "sha256:c9e1f2d0db7ddb9a704c2a0217be31214e91a4fe1dea1efad19ae42ba0c285c9"},
|
||||||
]
|
]
|
||||||
gitpython = [
|
gitpython = [
|
||||||
{file = "GitPython-3.1.8-py3-none-any.whl", hash = "sha256:1858f4fd089abe92ae465f01d5aaaf55e937eca565fb2c1fce35a51b5f85c910"},
|
{file = "GitPython-3.1.9-py3-none-any.whl", hash = "sha256:138016d519bf4dd55b22c682c904ed2fd0235c3612b2f8f65ce218ff358deed8"},
|
||||||
{file = "GitPython-3.1.8.tar.gz", hash = "sha256:080bf8e2cf1a2b907634761c2eaefbe83b69930c94c66ad11b65a8252959f912"},
|
{file = "GitPython-3.1.9.tar.gz", hash = "sha256:a03f728b49ce9597a6655793207c6ab0da55519368ff5961e4a74ae475b9fa8e"},
|
||||||
]
|
]
|
||||||
importlib-metadata = [
|
importlib-metadata = [
|
||||||
{file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"},
|
{file = "importlib_metadata-2.0.0-py2.py3-none-any.whl", hash = "sha256:cefa1a2f919b866c5beb7c9f7b0ebb4061f30a8a9bf16d609b000e2dfaceb9c3"},
|
||||||
@ -740,17 +730,13 @@ iso8601 = [
|
|||||||
{file = "iso8601-0.1.13.tar.gz", hash = "sha256:f7dec22af52025d4526be94cc1303c7d8f5379b746a3f54a8c8446384392eeb1"},
|
{file = "iso8601-0.1.13.tar.gz", hash = "sha256:f7dec22af52025d4526be94cc1303c7d8f5379b746a3f54a8c8446384392eeb1"},
|
||||||
]
|
]
|
||||||
isort = [
|
isort = [
|
||||||
{file = "isort-5.5.3-py3-none-any.whl", hash = "sha256:c16eaa7432a1c004c585d79b12ad080c6c421dd18fe27982ca11f95e6898e432"},
|
{file = "isort-5.6.1-py3-none-any.whl", hash = "sha256:dd3211f513f4a92ec1ec1876fc1dc3c686649c349d49523f5b5adbb0814e5960"},
|
||||||
{file = "isort-5.5.3.tar.gz", hash = "sha256:6187a9f1ce8784cbc6d1b88790a43e6083a6302f03e9ae482acc0f232a98c843"},
|
{file = "isort-5.6.1.tar.gz", hash = "sha256:2f510f34ae18a8d0958c53eec51ef84fd099f07c4c639676525acbcd7b5bd3ff"},
|
||||||
]
|
]
|
||||||
mccabe = [
|
mccabe = [
|
||||||
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
|
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
|
||||||
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
||||||
]
|
]
|
||||||
more-itertools = [
|
|
||||||
{file = "more-itertools-8.5.0.tar.gz", hash = "sha256:6f83822ae94818eae2612063a5101a7311e68ae8002005b5e05f03fd74a86a20"},
|
|
||||||
{file = "more_itertools-8.5.0-py3-none-any.whl", hash = "sha256:9b30f12df9393f0d28af9210ff8efe48d10c94f73e5daf886f10c4b0b0b4f03c"},
|
|
||||||
]
|
|
||||||
packaging = [
|
packaging = [
|
||||||
{file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"},
|
{file = "packaging-20.4-py2.py3-none-any.whl", hash = "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"},
|
||||||
{file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"},
|
{file = "packaging-20.4.tar.gz", hash = "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8"},
|
||||||
@ -811,11 +797,11 @@ pyparsing = [
|
|||||||
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
{file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"},
|
||||||
]
|
]
|
||||||
pypika = [
|
pypika = [
|
||||||
{file = "PyPika-0.40.0.tar.gz", hash = "sha256:659d307f7e531b66813619cbce08ecb97eeb302feabbd816ae8844b99496298b"},
|
{file = "PyPika-0.42.1.tar.gz", hash = "sha256:f9466259179d5cb12d6cf3d453f4370a511039a6dd88fcb5089f22ba8824b408"},
|
||||||
]
|
]
|
||||||
pytest = [
|
pytest = [
|
||||||
{file = "pytest-6.0.2-py3-none-any.whl", hash = "sha256:0e37f61339c4578776e090c3b8f6b16ce4db333889d65d0efb305243ec544b40"},
|
{file = "pytest-6.1.1-py3-none-any.whl", hash = "sha256:7a8190790c17d79a11f847fba0b004ee9a8122582ebff4729a082c109e81a4c9"},
|
||||||
{file = "pytest-6.0.2.tar.gz", hash = "sha256:c8f57c2a30983f469bf03e68cdfa74dc474ce56b8f280ddcb080dfd91df01043"},
|
{file = "pytest-6.1.1.tar.gz", hash = "sha256:8f593023c1a0f916110285b6efd7f99db07d59546e3d8c36fc60e2ab05d3be92"},
|
||||||
]
|
]
|
||||||
pytest-asyncio = [
|
pytest-asyncio = [
|
||||||
{file = "pytest-asyncio-0.14.0.tar.gz", hash = "sha256:9882c0c6b24429449f5f969a5158b528f39bde47dc32e85b9f0403965017e700"},
|
{file = "pytest-asyncio-0.14.0.tar.gz", hash = "sha256:9882c0c6b24429449f5f969a5158b528f39bde47dc32e85b9f0403965017e700"},
|
||||||
@ -847,26 +833,33 @@ pyyaml = [
|
|||||||
{file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
|
{file = "PyYAML-5.3.1.tar.gz", hash = "sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d"},
|
||||||
]
|
]
|
||||||
regex = [
|
regex = [
|
||||||
{file = "regex-2020.7.14-cp27-cp27m-win32.whl", hash = "sha256:e46d13f38cfcbb79bfdb2964b0fe12561fe633caf964a77a5f8d4e45fe5d2ef7"},
|
{file = "regex-2020.9.27-cp27-cp27m-win32.whl", hash = "sha256:d23a18037313714fb3bb5a94434d3151ee4300bae631894b1ac08111abeaa4a3"},
|
||||||
{file = "regex-2020.7.14-cp27-cp27m-win_amd64.whl", hash = "sha256:6961548bba529cac7c07af2fd4d527c5b91bb8fe18995fed6044ac22b3d14644"},
|
{file = "regex-2020.9.27-cp27-cp27m-win_amd64.whl", hash = "sha256:84e9407db1b2eb368b7ecc283121b5e592c9aaedbe8c78b1a2f1102eb2e21d19"},
|
||||||
{file = "regex-2020.7.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c50a724d136ec10d920661f1442e4a8b010a4fe5aebd65e0c2241ea41dbe93dc"},
|
{file = "regex-2020.9.27-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:5f18875ac23d9aa2f060838e8b79093e8bb2313dbaaa9f54c6d8e52a5df097be"},
|
||||||
{file = "regex-2020.7.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8a51f2c6d1f884e98846a0a9021ff6861bdb98457879f412fdc2b42d14494067"},
|
{file = "regex-2020.9.27-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ae91972f8ac958039920ef6e8769277c084971a142ce2b660691793ae44aae6b"},
|
||||||
{file = "regex-2020.7.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9c568495e35599625f7b999774e29e8d6b01a6fb684d77dee1f56d41b11b40cd"},
|
{file = "regex-2020.9.27-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:9a02d0ae31d35e1ec12a4ea4d4cca990800f66a917d0fb997b20fbc13f5321fc"},
|
||||||
{file = "regex-2020.7.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:51178c738d559a2d1071ce0b0f56e57eb315bcf8f7d4cf127674b533e3101f88"},
|
{file = "regex-2020.9.27-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:ebbe29186a3d9b0c591e71b7393f1ae08c83cb2d8e517d2a822b8f7ec99dfd8b"},
|
||||||
{file = "regex-2020.7.14-cp36-cp36m-win32.whl", hash = "sha256:9eddaafb3c48e0900690c1727fba226c4804b8e6127ea409689c3bb492d06de4"},
|
{file = "regex-2020.9.27-cp36-cp36m-win32.whl", hash = "sha256:4707f3695b34335afdfb09be3802c87fa0bc27030471dbc082f815f23688bc63"},
|
||||||
{file = "regex-2020.7.14-cp36-cp36m-win_amd64.whl", hash = "sha256:14a53646369157baa0499513f96091eb70382eb50b2c82393d17d7ec81b7b85f"},
|
{file = "regex-2020.9.27-cp36-cp36m-win_amd64.whl", hash = "sha256:9bc13e0d20b97ffb07821aa3e113f9998e84994fe4d159ffa3d3a9d1b805043b"},
|
||||||
{file = "regex-2020.7.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1269fef3167bb52631ad4fa7dd27bf635d5a0790b8e6222065d42e91bede4162"},
|
{file = "regex-2020.9.27-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:f1b3afc574a3db3b25c89161059d857bd4909a1269b0b3cb3c904677c8c4a3f7"},
|
||||||
{file = "regex-2020.7.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d0a5095d52b90ff38592bbdc2644f17c6d495762edf47d876049cfd2968fbccf"},
|
{file = "regex-2020.9.27-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5533a959a1748a5c042a6da71fe9267a908e21eded7a4f373efd23a2cbdb0ecc"},
|
||||||
{file = "regex-2020.7.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:4c037fd14c5f4e308b8370b447b469ca10e69427966527edcab07f52d88388f7"},
|
{file = "regex-2020.9.27-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:1fe0a41437bbd06063aa184c34804efa886bcc128222e9916310c92cd54c3b4c"},
|
||||||
{file = "regex-2020.7.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:bc3d98f621898b4a9bc7fecc00513eec8f40b5b83913d74ccb445f037d58cd89"},
|
{file = "regex-2020.9.27-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:c570f6fa14b9c4c8a4924aaad354652366577b4f98213cf76305067144f7b100"},
|
||||||
{file = "regex-2020.7.14-cp37-cp37m-win32.whl", hash = "sha256:46bac5ca10fb748d6c55843a931855e2727a7a22584f302dd9bb1506e69f83f6"},
|
{file = "regex-2020.9.27-cp37-cp37m-win32.whl", hash = "sha256:eda4771e0ace7f67f58bc5b560e27fb20f32a148cbc993b0c3835970935c2707"},
|
||||||
{file = "regex-2020.7.14-cp37-cp37m-win_amd64.whl", hash = "sha256:0dc64ee3f33cd7899f79a8d788abfbec168410be356ed9bd30bbd3f0a23a7204"},
|
{file = "regex-2020.9.27-cp37-cp37m-win_amd64.whl", hash = "sha256:60b0e9e6dc45683e569ec37c55ac20c582973841927a85f2d8a7d20ee80216ab"},
|
||||||
{file = "regex-2020.7.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:5ea81ea3dbd6767873c611687141ec7b06ed8bab43f68fad5b7be184a920dc99"},
|
{file = "regex-2020.9.27-cp38-cp38-manylinux1_i686.whl", hash = "sha256:088afc8c63e7bd187a3c70a94b9e50ab3f17e1d3f52a32750b5b77dbe99ef5ef"},
|
||||||
{file = "regex-2020.7.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bbb332d45b32df41200380fff14712cb6093b61bd142272a10b16778c418e98e"},
|
{file = "regex-2020.9.27-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:eaf548d117b6737df379fdd53bdde4f08870e66d7ea653e230477f071f861121"},
|
||||||
{file = "regex-2020.7.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:c11d6033115dc4887c456565303f540c44197f4fc1a2bfb192224a301534888e"},
|
{file = "regex-2020.9.27-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:41bb65f54bba392643557e617316d0d899ed5b4946dccee1cb6696152b29844b"},
|
||||||
{file = "regex-2020.7.14-cp38-cp38-win32.whl", hash = "sha256:d6cff2276e502b86a25fd10c2a96973fdb45c7a977dca2138d661417f3728341"},
|
{file = "regex-2020.9.27-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:8d69cef61fa50c8133382e61fd97439de1ae623fe943578e477e76a9d9471637"},
|
||||||
{file = "regex-2020.7.14-cp38-cp38-win_amd64.whl", hash = "sha256:7a2dd66d2d4df34fa82c9dc85657c5e019b87932019947faece7983f2089a840"},
|
{file = "regex-2020.9.27-cp38-cp38-win32.whl", hash = "sha256:f2388013e68e750eaa16ccbea62d4130180c26abb1d8e5d584b9baf69672b30f"},
|
||||||
{file = "regex-2020.7.14.tar.gz", hash = "sha256:3a3af27a8d23143c49a3420efe5b3f8cf1a48c6fc8bc6856b03f638abc1833bb"},
|
{file = "regex-2020.9.27-cp38-cp38-win_amd64.whl", hash = "sha256:4318d56bccfe7d43e5addb272406ade7a2274da4b70eb15922a071c58ab0108c"},
|
||||||
|
{file = "regex-2020.9.27-cp39-cp39-manylinux1_i686.whl", hash = "sha256:84cada8effefe9a9f53f9b0d2ba9b7b6f5edf8d2155f9fdbe34616e06ececf81"},
|
||||||
|
{file = "regex-2020.9.27-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:816064fc915796ea1f26966163f6845de5af78923dfcecf6551e095f00983650"},
|
||||||
|
{file = "regex-2020.9.27-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:5d892a4f1c999834eaa3c32bc9e8b976c5825116cde553928c4c8e7e48ebda67"},
|
||||||
|
{file = "regex-2020.9.27-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:c9443124c67b1515e4fe0bb0aa18df640965e1030f468a2a5dc2589b26d130ad"},
|
||||||
|
{file = "regex-2020.9.27-cp39-cp39-win32.whl", hash = "sha256:49f23ebd5ac073765ecbcf046edc10d63dcab2f4ae2bce160982cb30df0c0302"},
|
||||||
|
{file = "regex-2020.9.27-cp39-cp39-win_amd64.whl", hash = "sha256:3d20024a70b97b4f9546696cbf2fd30bae5f42229fbddf8661261b1eaff0deb7"},
|
||||||
|
{file = "regex-2020.9.27.tar.gz", hash = "sha256:a6f32aea4260dfe0e55dc9733ea162ea38f0ea86aa7d0f77b15beac5bf7b369d"},
|
||||||
]
|
]
|
||||||
six = [
|
six = [
|
||||||
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
|
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
|
||||||
@ -916,6 +909,6 @@ typing-extensions = [
|
|||||||
{file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
|
{file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"},
|
||||||
]
|
]
|
||||||
zipp = [
|
zipp = [
|
||||||
{file = "zipp-3.2.0-py3-none-any.whl", hash = "sha256:43f4fa8d8bb313e65d8323a3952ef8756bf40f9a5c3ea7334be23ee4ec8278b6"},
|
{file = "zipp-3.3.0-py3-none-any.whl", hash = "sha256:eed8ec0b8d1416b2ca33516a37a08892442f3954dee131e92cfd92d8fe3e7066"},
|
||||||
{file = "zipp-3.2.0.tar.gz", hash = "sha256:b52f22895f4cfce194bc8172f3819ee8de7540aa6d873535a8668b730b8b411f"},
|
{file = "zipp-3.3.0.tar.gz", hash = "sha256:64ad89efee774d1897a58607895d80789c59778ea02185dd846ac38394a8642b"},
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[tool.poetry]
|
[tool.poetry]
|
||||||
name = "aerich"
|
name = "aerich"
|
||||||
version = "0.2.5"
|
version = "0.3.0"
|
||||||
description = "A database migrations tool for Tortoise ORM."
|
description = "A database migrations tool for Tortoise ORM."
|
||||||
authors = ["long2ice <long2ice@gmail.com>"]
|
authors = ["long2ice <long2ice@gmail.com>"]
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user