Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
20aebc4413 | ||
|
f8e1f9ff44 | ||
|
ab31445fb2 | ||
|
28d19a4b7b | ||
|
9da99824fe | ||
|
75db7cea60 | ||
|
d777c9c278 | ||
|
e9b76bdd35 | ||
|
8b7864d886 | ||
|
bef45941f2 | ||
|
7b472d7a84 | ||
|
1f0a6dfb50 | ||
|
36282f123f | ||
|
3cd4e24050 | ||
|
f8c2f1b551 | ||
|
131d97a3d6 | ||
|
1a0371e977 | ||
|
e5b092fd08 | ||
|
7a109f3c79 | ||
|
8c2ecbaef1 | ||
|
b141363c51 | ||
|
9dd474d79f | ||
|
e4bb9d838e | ||
|
029d522c79 | ||
|
d6627906c7 | ||
|
3c88833154 | ||
|
8f68f08eba | ||
|
60ba6963fd | ||
|
4c35c44bd2 | ||
|
bdeaf5495e | ||
|
db33059ec9 | ||
|
44b96058f8 | ||
|
abff753b6a | ||
|
dcd8441a05 | ||
|
b4a735b814 | ||
|
83ba13e99a | ||
|
d7b1c07d13 | ||
|
1ac16188fc | ||
|
4abc464ce0 | ||
|
d4430cec0d | ||
|
0b01fa38d8 | ||
|
801dde15be | ||
|
75480e2041 | ||
|
45129cef9f | ||
|
3a0dd2355d | ||
|
0e71bc16ae | ||
|
40c7ef7fd6 | ||
|
7a826df43f | ||
|
b1b9cc1454 |
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@@ -2,10 +2,10 @@ name: ci
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- master
|
||||
- main
|
||||
pull_request:
|
||||
branches-ignore:
|
||||
- master
|
||||
- main
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
|
32
CHANGELOG.md
32
CHANGELOG.md
@@ -1,7 +1,39 @@
|
||||
# ChangeLog
|
||||
|
||||
## 0.7
|
||||
|
||||
### 0.7.1
|
||||
|
||||
- Fix syntax error with python3.8.10. (#265)
|
||||
- Fix sql generate error. (#263)
|
||||
- Fix initialize an empty database. (#267)
|
||||
|
||||
### 0.7.1rc1
|
||||
|
||||
- Fix postgres sql error (#263)
|
||||
|
||||
### 0.7.0
|
||||
|
||||
**Now aerich use `.py` file to record versions.**
|
||||
|
||||
Upgrade Note:
|
||||
|
||||
1. Drop `aerich` table
|
||||
2. Delete `migrations/models` folder
|
||||
3. Run `aerich init-db`
|
||||
|
||||
- Improve `inspectdb` adding support to `postgresql::numeric` data type
|
||||
- Add support for dynamically load DDL classes easing to add support to
|
||||
new databases without changing `Migrate` class logic
|
||||
- Fix decimal field change. (#246)
|
||||
- Support add/remove field with index.
|
||||
|
||||
## 0.6
|
||||
|
||||
### 0.6.3
|
||||
|
||||
- Improve `inspectdb` and support `postgres` & `sqlite`.
|
||||
|
||||
### 0.6.2
|
||||
|
||||
- Support migration for specified index. (#203)
|
||||
|
9
Makefile
9
Makefile
@@ -15,13 +15,12 @@ deps:
|
||||
@poetry install -E asyncpg -E asyncmy
|
||||
|
||||
style: deps
|
||||
isort -src $(checkfiles)
|
||||
black $(black_opts) $(checkfiles)
|
||||
@isort -src $(checkfiles)
|
||||
@black $(black_opts) $(checkfiles)
|
||||
|
||||
check: deps
|
||||
black --check $(black_opts) $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
|
||||
flake8 $(checkfiles)
|
||||
bandit -x tests -r $(checkfiles)
|
||||
@black --check $(black_opts) $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
|
||||
@pflake8 $(checkfiles)
|
||||
|
||||
test: deps
|
||||
$(py_warn) TEST_DB=sqlite://:memory: py.test
|
||||
|
53
README.md
53
README.md
@@ -101,11 +101,11 @@ e.g. `aerich --app other_models init-db`.
|
||||
```shell
|
||||
> aerich migrate --name drop_column
|
||||
|
||||
Success migrate 1_202029051520102929_drop_column.sql
|
||||
Success migrate 1_202029051520102929_drop_column.py
|
||||
```
|
||||
|
||||
Format of migrate filename is
|
||||
`{version_num}_{datetime}_{name|update}.sql`.
|
||||
`{version_num}_{datetime}_{name|update}.py`.
|
||||
|
||||
If `aerich` guesses you are renaming a column, it will ask `Rename {old_column} to {new_column} [True]`. You can choose
|
||||
`True` to rename column without column drop, or choose `False` to drop the column then create. Note that the latter may
|
||||
@@ -116,7 +116,7 @@ lose data.
|
||||
```shell
|
||||
> aerich upgrade
|
||||
|
||||
Success upgrade 1_202029051520102929_drop_column.sql
|
||||
Success upgrade 1_202029051520102929_drop_column.py
|
||||
```
|
||||
|
||||
Now your db is migrated to latest.
|
||||
@@ -142,7 +142,7 @@ Options:
|
||||
```shell
|
||||
> aerich downgrade
|
||||
|
||||
Success downgrade 1_202029051520102929_drop_column.sql
|
||||
Success downgrade 1_202029051520102929_drop_column.py
|
||||
```
|
||||
|
||||
Now your db is rolled back to the specified version.
|
||||
@@ -152,7 +152,7 @@ Now your db is rolled back to the specified version.
|
||||
```shell
|
||||
> aerich history
|
||||
|
||||
1_202029051520102929_drop_column.sql
|
||||
1_202029051520102929_drop_column.py
|
||||
```
|
||||
|
||||
### Show heads to be migrated
|
||||
@@ -160,12 +160,12 @@ Now your db is rolled back to the specified version.
|
||||
```shell
|
||||
> aerich heads
|
||||
|
||||
1_202029051520102929_drop_column.sql
|
||||
1_202029051520102929_drop_column.py
|
||||
```
|
||||
|
||||
### Inspect db tables to TortoiseORM model
|
||||
|
||||
Currently `inspectdb` only supports MySQL.
|
||||
Currently `inspectdb` support MySQL & Postgres & SQLite.
|
||||
|
||||
```shell
|
||||
Usage: aerich inspectdb [OPTIONS]
|
||||
@@ -189,7 +189,44 @@ Inspect a specified table in the default app and redirect to `models.py`:
|
||||
aerich inspectdb -t user > models.py
|
||||
```
|
||||
|
||||
Note that this command is limited and cannot infer some fields, such as `IntEnumField`, `ForeignKeyField`, and others.
|
||||
For example, you table is:
|
||||
|
||||
```sql
|
||||
CREATE TABLE `test`
|
||||
(
|
||||
`id` int NOT NULL AUTO_INCREMENT,
|
||||
`decimal` decimal(10, 2) NOT NULL,
|
||||
`date` date DEFAULT NULL,
|
||||
`datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
`time` time DEFAULT NULL,
|
||||
`float` float DEFAULT NULL,
|
||||
`string` varchar(200) COLLATE utf8mb4_general_ci DEFAULT NULL,
|
||||
`tinyint` tinyint DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `asyncmy_string_index` (`string`)
|
||||
) ENGINE = InnoDB
|
||||
DEFAULT CHARSET = utf8mb4
|
||||
COLLATE = utf8mb4_general_ci
|
||||
```
|
||||
|
||||
Now run `aerich inspectdb -t test` to see the generated model:
|
||||
|
||||
```python
|
||||
from tortoise import Model, fields
|
||||
|
||||
|
||||
class Test(Model):
|
||||
date = fields.DateField(null=True, )
|
||||
datetime = fields.DatetimeField(auto_now=True, )
|
||||
decimal = fields.DecimalField(max_digits=10, decimal_places=2, )
|
||||
float = fields.FloatField(null=True, )
|
||||
id = fields.IntField(pk=True, )
|
||||
string = fields.CharField(max_length=200, null=True, )
|
||||
time = fields.TimeField(null=True, )
|
||||
tinyint = fields.BooleanField(null=True, )
|
||||
```
|
||||
|
||||
Note that this command is limited and can't infer some fields, such as `IntEnumField`, `ForeignKeyField`, and others.
|
||||
|
||||
### Multiple databases
|
||||
|
||||
|
@@ -8,15 +8,16 @@ from tortoise.transactions import in_transaction
|
||||
from tortoise.utils import get_schema_sql
|
||||
|
||||
from aerich.exceptions import DowngradeError
|
||||
from aerich.inspectdb import InspectDb
|
||||
from aerich.migrate import Migrate
|
||||
from aerich.inspectdb.mysql import InspectMySQL
|
||||
from aerich.inspectdb.postgres import InspectPostgres
|
||||
from aerich.inspectdb.sqlite import InspectSQLite
|
||||
from aerich.migrate import MIGRATE_TEMPLATE, Migrate
|
||||
from aerich.models import Aerich
|
||||
from aerich.utils import (
|
||||
get_app_connection,
|
||||
get_app_connection_name,
|
||||
get_models_describe,
|
||||
get_version_content_from_file,
|
||||
write_version_file,
|
||||
import_py_file,
|
||||
)
|
||||
|
||||
|
||||
@@ -47,10 +48,9 @@ class Command:
|
||||
get_app_connection_name(self.tortoise_config, self.app)
|
||||
) as conn:
|
||||
file_path = Path(Migrate.migrate_location, version_file)
|
||||
content = get_version_content_from_file(file_path)
|
||||
upgrade_query_list = content.get("upgrade")
|
||||
for upgrade_query in upgrade_query_list:
|
||||
await conn.execute_script(upgrade_query)
|
||||
m = import_py_file(file_path)
|
||||
upgrade = getattr(m, "upgrade")
|
||||
await conn.execute_script(await upgrade(conn))
|
||||
await Aerich.create(
|
||||
version=version_file,
|
||||
app=self.app,
|
||||
@@ -79,12 +79,12 @@ class Command:
|
||||
get_app_connection_name(self.tortoise_config, self.app)
|
||||
) as conn:
|
||||
file_path = Path(Migrate.migrate_location, file)
|
||||
content = get_version_content_from_file(file_path)
|
||||
downgrade_query_list = content.get("downgrade")
|
||||
if not downgrade_query_list:
|
||||
m = import_py_file(file_path)
|
||||
downgrade = getattr(m, "downgrade")
|
||||
downgrade_sql = await downgrade(conn)
|
||||
if not downgrade_sql.strip():
|
||||
raise DowngradeError("No downgrade items found")
|
||||
for downgrade_query in downgrade_query_list:
|
||||
await conn.execute_query(downgrade_query)
|
||||
await conn.execute_script(downgrade_sql)
|
||||
await version.delete()
|
||||
if delete:
|
||||
os.unlink(file_path)
|
||||
@@ -100,16 +100,22 @@ class Command:
|
||||
return ret
|
||||
|
||||
async def history(self):
|
||||
ret = []
|
||||
versions = Migrate.get_all_version_files()
|
||||
for version in versions:
|
||||
ret.append(version)
|
||||
return ret
|
||||
return [version for version in versions]
|
||||
|
||||
async def inspectdb(self, tables: List[str]):
|
||||
async def inspectdb(self, tables: List[str] = None) -> str:
|
||||
connection = get_app_connection(self.tortoise_config, self.app)
|
||||
inspect = InspectDb(connection, tables)
|
||||
await inspect.inspect()
|
||||
dialect = connection.schema_generator.DIALECT
|
||||
if dialect == "mysql":
|
||||
cls = InspectMySQL
|
||||
elif dialect == "postgres":
|
||||
cls = InspectPostgres
|
||||
elif dialect == "sqlite":
|
||||
cls = InspectSQLite
|
||||
else:
|
||||
raise NotImplementedError(f"{dialect} is not supported")
|
||||
inspect = cls(connection, tables)
|
||||
return await inspect.inspect()
|
||||
|
||||
async def migrate(self, name: str = "update"):
|
||||
return await Migrate.migrate(name)
|
||||
@@ -132,7 +138,7 @@ class Command:
|
||||
app=app,
|
||||
content=get_models_describe(app),
|
||||
)
|
||||
content = {
|
||||
"upgrade": [schema],
|
||||
}
|
||||
write_version_file(Path(dirname, version), content)
|
||||
version_file = Path(dirname, version)
|
||||
content = MIGRATE_TEMPLATE.format(upgrade_sql=schema, downgrade_sql="")
|
||||
with open(version_file, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
|
@@ -26,11 +26,11 @@ def coro(f):
|
||||
def wrapper(*args, **kwargs):
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
# Close db connections at the end of all all but the cli group function
|
||||
# Close db connections at the end of all but the cli group function
|
||||
try:
|
||||
loop.run_until_complete(f(*args, **kwargs))
|
||||
finally:
|
||||
if f.__name__ != "cli":
|
||||
if f.__name__ not in ["cli", "init_db", "init"]:
|
||||
loop.run_until_complete(Tortoise.close_connections())
|
||||
|
||||
return wrapper
|
||||
@@ -54,10 +54,10 @@ async def cli(ctx: Context, config, app):
|
||||
|
||||
invoked_subcommand = ctx.invoked_subcommand
|
||||
if invoked_subcommand != "init":
|
||||
if not Path(config).exists():
|
||||
config_path = Path(config)
|
||||
if not config_path.exists():
|
||||
raise UsageError("You must exec init first", ctx=ctx)
|
||||
with open(config, "r") as f:
|
||||
content = f.read()
|
||||
content = config_path.read_text()
|
||||
doc = tomlkit.parse(content)
|
||||
try:
|
||||
tool = doc["tool"]["aerich"]
|
||||
@@ -192,9 +192,9 @@ async def init(ctx: Context, tortoise_orm, location, src_folder):
|
||||
# check that we can find the configuration, if not we can fail before the config file gets created
|
||||
add_src_path(src_folder)
|
||||
get_tortoise_config(ctx, tortoise_orm)
|
||||
if Path(config_file).exists():
|
||||
with open(config_file, "r") as f:
|
||||
content = f.read()
|
||||
config_path = Path(config_file)
|
||||
if config_path.exists():
|
||||
content = config_path.read_text()
|
||||
doc = tomlkit.parse(content)
|
||||
else:
|
||||
doc = tomlkit.parse("[tool.aerich]")
|
||||
@@ -204,8 +204,7 @@ async def init(ctx: Context, tortoise_orm, location, src_folder):
|
||||
table["src_folder"] = src_folder
|
||||
doc["tool"]["aerich"] = table
|
||||
|
||||
with open(config_file, "w") as f:
|
||||
f.write(tomlkit.dumps(doc))
|
||||
config_path.write_text(tomlkit.dumps(doc))
|
||||
|
||||
Path(location).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@@ -215,15 +214,17 @@ async def init(ctx: Context, tortoise_orm, location, src_folder):
|
||||
|
||||
@cli.command(help="Generate schema and generate app migrate location.")
|
||||
@click.option(
|
||||
"-s",
|
||||
"--safe",
|
||||
type=bool,
|
||||
is_flag=True,
|
||||
default=True,
|
||||
help="When set to true, creates the table only when it does not already exist.",
|
||||
show_default=True,
|
||||
)
|
||||
@click.pass_context
|
||||
@coro
|
||||
async def init_db(ctx: Context, safe):
|
||||
async def init_db(ctx: Context, safe: bool):
|
||||
command = ctx.obj["command"]
|
||||
app = command.app
|
||||
dirname = Path(command.location, app)
|
||||
@@ -249,7 +250,8 @@ async def init_db(ctx: Context, safe):
|
||||
@coro
|
||||
async def inspectdb(ctx: Context, table: List[str]):
|
||||
command = ctx.obj["command"]
|
||||
await command.inspectdb(table)
|
||||
ret = await command.inspectdb(table)
|
||||
click.secho(ret)
|
||||
|
||||
|
||||
def main():
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import base64
|
||||
import json
|
||||
import pickle # nosec: B301
|
||||
import pickle # nosec: B301,B403
|
||||
|
||||
from tortoise.indexes import Index
|
||||
|
||||
@@ -10,8 +10,8 @@ class JsonEncoder(json.JSONEncoder):
|
||||
if isinstance(obj, Index):
|
||||
return {
|
||||
"type": "index",
|
||||
"val": base64.b64encode(pickle.dumps(obj)).decode(),
|
||||
} # nosec: B301
|
||||
"val": base64.b64encode(pickle.dumps(obj)).decode(), # nosec: B301
|
||||
}
|
||||
else:
|
||||
return super().default(obj)
|
||||
|
||||
|
@@ -23,7 +23,12 @@ class BaseDDL:
|
||||
_DROP_INDEX_TEMPLATE = 'ALTER TABLE "{table_name}" DROP INDEX "{index_name}"'
|
||||
_ADD_FK_TEMPLATE = 'ALTER TABLE "{table_name}" ADD CONSTRAINT "{fk_name}" FOREIGN KEY ("{db_column}") REFERENCES "{table}" ("{field}") ON DELETE {on_delete}'
|
||||
_DROP_FK_TEMPLATE = 'ALTER TABLE "{table_name}" DROP FOREIGN KEY "{fk_name}"'
|
||||
_M2M_TABLE_TEMPLATE = 'CREATE TABLE "{table_name}" ("{backward_key}" {backward_type} NOT NULL REFERENCES "{backward_table}" ("{backward_field}") ON DELETE CASCADE,"{forward_key}" {forward_type} NOT NULL REFERENCES "{forward_table}" ("{forward_field}") ON DELETE {on_delete}){extra}{comment}'
|
||||
_M2M_TABLE_TEMPLATE = (
|
||||
'CREATE TABLE "{table_name}" (\n'
|
||||
' "{backward_key}" {backward_type} NOT NULL REFERENCES "{backward_table}" ("{backward_field}") ON DELETE CASCADE,\n'
|
||||
' "{forward_key}" {forward_type} NOT NULL REFERENCES "{forward_table}" ("{forward_field}") ON DELETE {on_delete}\n'
|
||||
"){extra}{comment}"
|
||||
)
|
||||
_MODIFY_COLUMN_TEMPLATE = 'ALTER TABLE "{table_name}" MODIFY COLUMN {column}'
|
||||
_CHANGE_COLUMN_TEMPLATE = (
|
||||
'ALTER TABLE "{table_name}" CHANGE {old_column_name} {new_column_name} {new_column_type}'
|
||||
@@ -78,15 +83,11 @@ class BaseDDL:
|
||||
auto_now_add = field_describe.get("auto_now_add", False)
|
||||
auto_now = field_describe.get("auto_now", False)
|
||||
if default is not None or auto_now_add:
|
||||
if (
|
||||
field_describe.get("field_type")
|
||||
in [
|
||||
"UUIDField",
|
||||
"TextField",
|
||||
"JSONField",
|
||||
]
|
||||
or is_default_function(default)
|
||||
):
|
||||
if field_describe.get("field_type") in [
|
||||
"UUIDField",
|
||||
"TextField",
|
||||
"JSONField",
|
||||
] or is_default_function(default):
|
||||
default = ""
|
||||
else:
|
||||
try:
|
||||
@@ -184,7 +185,7 @@ class BaseDDL:
|
||||
"idx" if not unique else "uid", model, field_names
|
||||
),
|
||||
table_name=model._meta.db_table,
|
||||
column_names=", ".join([self.schema_generator.quote(f) for f in field_names]),
|
||||
column_names=", ".join(self.schema_generator.quote(f) for f in field_names),
|
||||
)
|
||||
|
||||
def drop_index(self, model: "Type[Model]", field_names: List[str], unique=False):
|
||||
|
@@ -22,6 +22,11 @@ class MysqlDDL(BaseDDL):
|
||||
_DROP_INDEX_TEMPLATE = "ALTER TABLE `{table_name}` DROP INDEX `{index_name}`"
|
||||
_ADD_FK_TEMPLATE = "ALTER TABLE `{table_name}` ADD CONSTRAINT `{fk_name}` FOREIGN KEY (`{db_column}`) REFERENCES `{table}` (`{field}`) ON DELETE {on_delete}"
|
||||
_DROP_FK_TEMPLATE = "ALTER TABLE `{table_name}` DROP FOREIGN KEY `{fk_name}`"
|
||||
_M2M_TABLE_TEMPLATE = "CREATE TABLE `{table_name}` (`{backward_key}` {backward_type} NOT NULL REFERENCES `{backward_table}` (`{backward_field}`) ON DELETE CASCADE,`{forward_key}` {forward_type} NOT NULL REFERENCES `{forward_table}` (`{forward_field}`) ON DELETE CASCADE){extra}{comment}"
|
||||
_M2M_TABLE_TEMPLATE = (
|
||||
"CREATE TABLE `{table_name}` (\n"
|
||||
" `{backward_key}` {backward_type} NOT NULL REFERENCES `{backward_table}` (`{backward_field}`) ON DELETE CASCADE,\n"
|
||||
" `{forward_key}` {forward_type} NOT NULL REFERENCES `{forward_table}` (`{forward_field}`) ON DELETE CASCADE\n"
|
||||
"){extra}{comment}"
|
||||
)
|
||||
_MODIFY_COLUMN_TEMPLATE = "ALTER TABLE `{table_name}` MODIFY COLUMN {column}"
|
||||
_RENAME_TABLE_TEMPLATE = "ALTER TABLE `{old_table_name}` RENAME TO `{new_table_name}`"
|
||||
|
@@ -1,87 +0,0 @@
|
||||
import sys
|
||||
from typing import List, Optional
|
||||
|
||||
from ddlparse import DdlParse
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
|
||||
class InspectDb:
|
||||
_table_template = "class {table}(Model):\n"
|
||||
_field_template_mapping = {
|
||||
"INT": " {field} = fields.IntField({pk}{unique}{comment})",
|
||||
"SMALLINT": " {field} = fields.IntField({pk}{unique}{comment})",
|
||||
"TINYINT": " {field} = fields.BooleanField({null}{default}{comment})",
|
||||
"VARCHAR": " {field} = fields.CharField({pk}{unique}{length}{null}{default}{comment})",
|
||||
"LONGTEXT": " {field} = fields.TextField({null}{default}{comment})",
|
||||
"TEXT": " {field} = fields.TextField({null}{default}{comment})",
|
||||
"DATETIME": " {field} = fields.DatetimeField({null}{default}{comment})",
|
||||
"FLOAT": " {field} = fields.FloatField({null}{default}{comment})",
|
||||
"DATE": " {field} = fields.DateField({null}{default}{comment})",
|
||||
}
|
||||
|
||||
def __init__(self, conn: BaseDBAsyncClient, tables: Optional[List[str]] = None):
|
||||
self.conn = conn
|
||||
self.tables = tables
|
||||
self.DIALECT = conn.schema_generator.DIALECT
|
||||
|
||||
async def show_create_tables(self):
|
||||
if self.DIALECT == "mysql":
|
||||
if not self.tables:
|
||||
sql_tables = f"SELECT table_name FROM information_schema.tables WHERE table_schema = '{self.conn.database}';" # nosec: B608
|
||||
ret = await self.conn.execute_query(sql_tables)
|
||||
self.tables = map(lambda x: x["TABLE_NAME"], ret[1])
|
||||
for table in self.tables:
|
||||
sql_show_create_table = f"SHOW CREATE TABLE {table}"
|
||||
ret = await self.conn.execute_query(sql_show_create_table)
|
||||
yield ret[1][0]["Create Table"]
|
||||
else:
|
||||
raise NotImplementedError("Currently only support MySQL")
|
||||
|
||||
async def inspect(self):
|
||||
ddl_list = self.show_create_tables()
|
||||
result = "from tortoise import Model, fields\n\n\n"
|
||||
tables = []
|
||||
async for ddl in ddl_list:
|
||||
parser = DdlParse(ddl, DdlParse.DATABASE.mysql)
|
||||
table = parser.parse()
|
||||
name = table.name.title()
|
||||
columns = table.columns
|
||||
fields = []
|
||||
model = self._table_template.format(table=name)
|
||||
for column_name, column in columns.items():
|
||||
comment = default = length = unique = null = pk = ""
|
||||
if column.primary_key:
|
||||
pk = "pk=True, "
|
||||
if column.unique:
|
||||
unique = "unique=True, "
|
||||
if column.data_type == "VARCHAR":
|
||||
length = f"max_length={column.length}, "
|
||||
if not column.not_null:
|
||||
null = "null=True, "
|
||||
if column.default is not None:
|
||||
if column.data_type == "TINYINT":
|
||||
default = f"default={'True' if column.default == '1' else 'False'}, "
|
||||
elif column.data_type == "DATETIME":
|
||||
if "CURRENT_TIMESTAMP" in column.default:
|
||||
if "ON UPDATE CURRENT_TIMESTAMP" in ddl:
|
||||
default = "auto_now_add=True, "
|
||||
else:
|
||||
default = "auto_now=True, "
|
||||
else:
|
||||
default = f"default={column.default}, "
|
||||
|
||||
if column.comment:
|
||||
comment = f"description='{column.comment}', "
|
||||
|
||||
field = self._field_template_mapping[column.data_type].format(
|
||||
field=column_name,
|
||||
pk=pk,
|
||||
unique=unique,
|
||||
length=length,
|
||||
null=null,
|
||||
default=default,
|
||||
comment=comment,
|
||||
)
|
||||
fields.append(field)
|
||||
tables.append(model + "\n".join(fields))
|
||||
sys.stdout.write(result + "\n\n\n".join(tables))
|
168
aerich/inspectdb/__init__.py
Normal file
168
aerich/inspectdb/__init__.py
Normal file
@@ -0,0 +1,168 @@
|
||||
from typing import Any, List, Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
|
||||
class Column(BaseModel):
|
||||
name: str
|
||||
data_type: str
|
||||
null: bool
|
||||
default: Any
|
||||
comment: Optional[str]
|
||||
pk: bool
|
||||
unique: bool
|
||||
index: bool
|
||||
length: Optional[int]
|
||||
extra: Optional[str]
|
||||
decimal_places: Optional[int]
|
||||
max_digits: Optional[int]
|
||||
|
||||
def translate(self) -> dict:
|
||||
comment = default = length = index = null = pk = ""
|
||||
if self.pk:
|
||||
pk = "pk=True, "
|
||||
else:
|
||||
if self.unique:
|
||||
index = "unique=True, "
|
||||
else:
|
||||
if self.index:
|
||||
index = "index=True, "
|
||||
if self.data_type in ["varchar", "VARCHAR"]:
|
||||
length = f"max_length={self.length}, "
|
||||
if self.data_type in ["decimal", "numeric"]:
|
||||
length_parts = []
|
||||
if self.max_digits:
|
||||
length_parts.append(f"max_digits={self.max_digits}")
|
||||
if self.decimal_places:
|
||||
length_parts.append(f"decimal_places={self.decimal_places}")
|
||||
length = ", ".join(length_parts)
|
||||
if self.null:
|
||||
null = "null=True, "
|
||||
if self.default is not None:
|
||||
if self.data_type in ["tinyint", "INT"]:
|
||||
default = f"default={'True' if self.default == '1' else 'False'}, "
|
||||
elif self.data_type == "bool":
|
||||
default = f"default={'True' if self.default == 'true' else 'False'}, "
|
||||
elif self.data_type in ["datetime", "timestamptz", "TIMESTAMP"]:
|
||||
if "CURRENT_TIMESTAMP" == self.default:
|
||||
if "DEFAULT_GENERATED on update CURRENT_TIMESTAMP" == self.extra:
|
||||
default = "auto_now=True, "
|
||||
else:
|
||||
default = "auto_now_add=True, "
|
||||
else:
|
||||
if "::" in self.default:
|
||||
default = f"default={self.default.split('::')[0]}, "
|
||||
elif self.default.endswith("()"):
|
||||
default = ""
|
||||
else:
|
||||
default = f"default={self.default}, "
|
||||
|
||||
if self.comment:
|
||||
comment = f"description='{self.comment}', "
|
||||
return {
|
||||
"name": self.name,
|
||||
"pk": pk,
|
||||
"index": index,
|
||||
"null": null,
|
||||
"default": default,
|
||||
"length": length,
|
||||
"comment": comment,
|
||||
}
|
||||
|
||||
|
||||
class Inspect:
|
||||
_table_template = "class {table}(Model):\n"
|
||||
|
||||
def __init__(self, conn: BaseDBAsyncClient, tables: Optional[List[str]] = None):
|
||||
self.conn = conn
|
||||
try:
|
||||
self.database = conn.database
|
||||
except AttributeError:
|
||||
pass
|
||||
self.tables = tables
|
||||
|
||||
@property
|
||||
def field_map(self) -> dict:
|
||||
raise NotImplementedError
|
||||
|
||||
async def inspect(self) -> str:
|
||||
if not self.tables:
|
||||
self.tables = await self.get_all_tables()
|
||||
result = "from tortoise import Model, fields\n\n\n"
|
||||
tables = []
|
||||
for table in self.tables:
|
||||
columns = await self.get_columns(table)
|
||||
fields = []
|
||||
model = self._table_template.format(table=table.title().replace("_", ""))
|
||||
for column in columns:
|
||||
field = self.field_map[column.data_type](**column.translate())
|
||||
fields.append(" " + field)
|
||||
tables.append(model + "\n".join(fields))
|
||||
return result + "\n\n\n".join(tables)
|
||||
|
||||
async def get_columns(self, table: str) -> List[Column]:
|
||||
raise NotImplementedError
|
||||
|
||||
async def get_all_tables(self) -> List[str]:
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def decimal_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.DecimalField({pk}{index}{length}{null}{default}{comment})".format(
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def time_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.TimeField({null}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def date_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.DateField({null}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def float_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.FloatField({null}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def datetime_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.DatetimeField({null}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def text_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.TextField({null}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def char_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.CharField({pk}{index}{length}{null}{default}{comment})".format(
|
||||
**kwargs
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def int_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.IntField({pk}{index}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def smallint_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.SmallIntField({pk}{index}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def bigint_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.BigIntField({pk}{index}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def bool_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.BooleanField({null}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def uuid_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.UUIDField({pk}{index}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def json_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.JSONField({null}{default}{comment})".format(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def binary_field(cls, **kwargs) -> str:
|
||||
return "{name} = fields.BinaryField({null}{default}{comment})".format(**kwargs)
|
69
aerich/inspectdb/mysql.py
Normal file
69
aerich/inspectdb/mysql.py
Normal file
@@ -0,0 +1,69 @@
|
||||
from typing import List
|
||||
|
||||
from aerich.inspectdb import Column, Inspect
|
||||
|
||||
|
||||
class InspectMySQL(Inspect):
|
||||
@property
|
||||
def field_map(self) -> dict:
|
||||
return {
|
||||
"int": self.int_field,
|
||||
"smallint": self.smallint_field,
|
||||
"tinyint": self.bool_field,
|
||||
"bigint": self.bigint_field,
|
||||
"varchar": self.char_field,
|
||||
"longtext": self.text_field,
|
||||
"text": self.text_field,
|
||||
"datetime": self.datetime_field,
|
||||
"float": self.float_field,
|
||||
"date": self.date_field,
|
||||
"time": self.time_field,
|
||||
"decimal": self.decimal_field,
|
||||
"json": self.json_field,
|
||||
"longblob": self.binary_field,
|
||||
}
|
||||
|
||||
async def get_all_tables(self) -> List[str]:
|
||||
sql = "select TABLE_NAME from information_schema.TABLES where TABLE_SCHEMA=%s"
|
||||
ret = await self.conn.execute_query_dict(sql, [self.database])
|
||||
return list(map(lambda x: x["TABLE_NAME"], ret))
|
||||
|
||||
async def get_columns(self, table: str) -> List[Column]:
|
||||
columns = []
|
||||
sql = """select c.*, s.NON_UNIQUE, s.INDEX_NAME
|
||||
from information_schema.COLUMNS c
|
||||
left join information_schema.STATISTICS s on c.TABLE_NAME = s.TABLE_NAME
|
||||
and c.TABLE_SCHEMA = s.TABLE_SCHEMA
|
||||
and c.COLUMN_NAME = s.COLUMN_NAME
|
||||
where c.TABLE_SCHEMA = %s
|
||||
and c.TABLE_NAME = %s"""
|
||||
ret = await self.conn.execute_query_dict(sql, [self.database, table])
|
||||
for row in ret:
|
||||
non_unique = row["NON_UNIQUE"]
|
||||
if non_unique is None:
|
||||
unique = False
|
||||
else:
|
||||
unique = not non_unique
|
||||
index_name = row["INDEX_NAME"]
|
||||
if index_name is None:
|
||||
index = False
|
||||
else:
|
||||
index = row["INDEX_NAME"] != "PRIMARY"
|
||||
columns.append(
|
||||
Column(
|
||||
name=row["COLUMN_NAME"],
|
||||
data_type=row["DATA_TYPE"],
|
||||
null=row["IS_NULLABLE"] == "YES",
|
||||
default=row["COLUMN_DEFAULT"],
|
||||
pk=row["COLUMN_KEY"] == "PRI",
|
||||
comment=row["COLUMN_COMMENT"],
|
||||
unique=row["COLUMN_KEY"] == "UNI",
|
||||
extra=row["EXTRA"],
|
||||
unque=unique,
|
||||
index=index,
|
||||
length=row["CHARACTER_MAXIMUM_LENGTH"],
|
||||
max_digits=row["NUMERIC_PRECISION"],
|
||||
decimal_places=row["NUMERIC_SCALE"],
|
||||
)
|
||||
)
|
||||
return columns
|
76
aerich/inspectdb/postgres.py
Normal file
76
aerich/inspectdb/postgres.py
Normal file
@@ -0,0 +1,76 @@
|
||||
from typing import List, Optional
|
||||
|
||||
from tortoise import BaseDBAsyncClient
|
||||
|
||||
from aerich.inspectdb import Column, Inspect
|
||||
|
||||
|
||||
class InspectPostgres(Inspect):
|
||||
def __init__(self, conn: BaseDBAsyncClient, tables: Optional[List[str]] = None):
|
||||
super().__init__(conn, tables)
|
||||
self.schema = self.conn.server_settings.get("schema") or "public"
|
||||
|
||||
@property
|
||||
def field_map(self) -> dict:
|
||||
return {
|
||||
"int4": self.int_field,
|
||||
"int8": self.int_field,
|
||||
"smallint": self.smallint_field,
|
||||
"varchar": self.char_field,
|
||||
"text": self.text_field,
|
||||
"bigint": self.bigint_field,
|
||||
"timestamptz": self.datetime_field,
|
||||
"float4": self.float_field,
|
||||
"float8": self.float_field,
|
||||
"date": self.date_field,
|
||||
"time": self.time_field,
|
||||
"decimal": self.decimal_field,
|
||||
"numeric": self.decimal_field,
|
||||
"uuid": self.uuid_field,
|
||||
"jsonb": self.json_field,
|
||||
"bytea": self.binary_field,
|
||||
"bool": self.bool_field,
|
||||
"timestamp": self.datetime_field,
|
||||
}
|
||||
|
||||
async def get_all_tables(self) -> List[str]:
|
||||
sql = "select TABLE_NAME from information_schema.TABLES where table_catalog=$1 and table_schema=$2"
|
||||
ret = await self.conn.execute_query_dict(sql, [self.database, self.schema])
|
||||
return list(map(lambda x: x["table_name"], ret))
|
||||
|
||||
async def get_columns(self, table: str) -> List[Column]:
|
||||
columns = []
|
||||
sql = f"""select c.column_name,
|
||||
col_description('public.{table}'::regclass, ordinal_position) as column_comment,
|
||||
t.constraint_type as column_key,
|
||||
udt_name as data_type,
|
||||
is_nullable,
|
||||
column_default,
|
||||
character_maximum_length,
|
||||
numeric_precision,
|
||||
numeric_scale
|
||||
from information_schema.constraint_column_usage const
|
||||
join information_schema.table_constraints t
|
||||
using (table_catalog, table_schema, table_name, constraint_catalog, constraint_schema, constraint_name)
|
||||
right join information_schema.columns c using (column_name, table_catalog, table_schema, table_name)
|
||||
where c.table_catalog = $1
|
||||
and c.table_name = $2
|
||||
and c.table_schema = $3"""
|
||||
ret = await self.conn.execute_query_dict(sql, [self.database, table, self.schema])
|
||||
for row in ret:
|
||||
columns.append(
|
||||
Column(
|
||||
name=row["column_name"],
|
||||
data_type=row["data_type"],
|
||||
null=row["is_nullable"] == "YES",
|
||||
default=row["column_default"],
|
||||
length=row["character_maximum_length"],
|
||||
max_digits=row["numeric_precision"],
|
||||
decimal_places=row["numeric_scale"],
|
||||
comment=row["column_comment"],
|
||||
pk=row["column_key"] == "PRIMARY KEY",
|
||||
unique=False, # can't get this simply
|
||||
index=False, # can't get this simply
|
||||
)
|
||||
)
|
||||
return columns
|
61
aerich/inspectdb/sqlite.py
Normal file
61
aerich/inspectdb/sqlite.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from typing import List
|
||||
|
||||
from aerich.inspectdb import Column, Inspect
|
||||
|
||||
|
||||
class InspectSQLite(Inspect):
|
||||
@property
|
||||
def field_map(self) -> dict:
|
||||
return {
|
||||
"INTEGER": self.int_field,
|
||||
"INT": self.bool_field,
|
||||
"SMALLINT": self.smallint_field,
|
||||
"VARCHAR": self.char_field,
|
||||
"TEXT": self.text_field,
|
||||
"TIMESTAMP": self.datetime_field,
|
||||
"REAL": self.float_field,
|
||||
"BIGINT": self.bigint_field,
|
||||
"DATE": self.date_field,
|
||||
"TIME": self.time_field,
|
||||
"JSON": self.json_field,
|
||||
"BLOB": self.binary_field,
|
||||
}
|
||||
|
||||
async def get_columns(self, table: str) -> List[Column]:
|
||||
columns = []
|
||||
sql = f"PRAGMA table_info({table})"
|
||||
ret = await self.conn.execute_query_dict(sql)
|
||||
columns_index = await self._get_columns_index(table)
|
||||
for row in ret:
|
||||
try:
|
||||
length = row["type"].split("(")[1].split(")")[0]
|
||||
except IndexError:
|
||||
length = None
|
||||
columns.append(
|
||||
Column(
|
||||
name=row["name"],
|
||||
data_type=row["type"].split("(")[0],
|
||||
null=row["notnull"] == 0,
|
||||
default=row["dflt_value"],
|
||||
length=length,
|
||||
pk=row["pk"] == 1,
|
||||
unique=columns_index.get(row["name"]) == "unique",
|
||||
index=columns_index.get(row["name"]) == "index",
|
||||
)
|
||||
)
|
||||
return columns
|
||||
|
||||
async def _get_columns_index(self, table: str):
|
||||
sql = f"PRAGMA index_list ({table})"
|
||||
indexes = await self.conn.execute_query_dict(sql)
|
||||
ret = {}
|
||||
for index in indexes:
|
||||
sql = f"PRAGMA index_info({index['name']})"
|
||||
index_info = (await self.conn.execute_query_dict(sql))[0]
|
||||
ret[index_info["name"]] = "unique" if index["unique"] else "index"
|
||||
return ret
|
||||
|
||||
async def get_all_tables(self) -> List[str]:
|
||||
sql = "select tbl_name from sqlite_master where type='table' and name!='sqlite_sequence'"
|
||||
ret = await self.conn.execute_query_dict(sql)
|
||||
return list(map(lambda x: x["tbl_name"], ret))
|
@@ -1,3 +1,4 @@
|
||||
import importlib
|
||||
import os
|
||||
from datetime import datetime
|
||||
from hashlib import md5
|
||||
@@ -12,12 +13,20 @@ from tortoise.indexes import Index
|
||||
|
||||
from aerich.ddl import BaseDDL
|
||||
from aerich.models import MAX_VERSION_LENGTH, Aerich
|
||||
from aerich.utils import (
|
||||
get_app_connection,
|
||||
get_models_describe,
|
||||
is_default_function,
|
||||
write_version_file,
|
||||
)
|
||||
from aerich.utils import get_app_connection, get_models_describe, is_default_function
|
||||
|
||||
MIGRATE_TEMPLATE = """from tortoise import BaseDBAsyncClient
|
||||
|
||||
|
||||
async def upgrade(db: BaseDBAsyncClient) -> str:
|
||||
return \"\"\"
|
||||
{upgrade_sql}\"\"\"
|
||||
|
||||
|
||||
async def downgrade(db: BaseDBAsyncClient) -> str:
|
||||
return \"\"\"
|
||||
{downgrade_sql}\"\"\"
|
||||
"""
|
||||
|
||||
|
||||
class Migrate:
|
||||
@@ -41,7 +50,7 @@ class Migrate:
|
||||
@classmethod
|
||||
def get_all_version_files(cls) -> List[str]:
|
||||
return sorted(
|
||||
filter(lambda x: x.endswith("sql"), os.listdir(cls.migrate_location)),
|
||||
filter(lambda x: x.endswith("py"), os.listdir(cls.migrate_location)),
|
||||
key=lambda x: int(x.split("_")[0]),
|
||||
)
|
||||
|
||||
@@ -63,6 +72,11 @@ class Migrate:
|
||||
ret = await connection.execute_query(sql)
|
||||
cls._db_version = ret[1][0].get("version")
|
||||
|
||||
@classmethod
|
||||
async def load_ddl_class(cls):
|
||||
ddl_dialect_module = importlib.import_module(f"aerich.ddl.{cls.dialect}")
|
||||
return getattr(ddl_dialect_module, f"{cls.dialect.capitalize()}DDL")
|
||||
|
||||
@classmethod
|
||||
async def init(cls, config: dict, app: str, location: str):
|
||||
await Tortoise.init(config=config)
|
||||
@@ -74,18 +88,8 @@ class Migrate:
|
||||
|
||||
connection = get_app_connection(config, app)
|
||||
cls.dialect = connection.schema_generator.DIALECT
|
||||
if cls.dialect == "mysql":
|
||||
from aerich.ddl.mysql import MysqlDDL
|
||||
|
||||
cls.ddl = MysqlDDL(connection)
|
||||
elif cls.dialect == "sqlite":
|
||||
from aerich.ddl.sqlite import SqliteDDL
|
||||
|
||||
cls.ddl = SqliteDDL(connection)
|
||||
elif cls.dialect == "postgres":
|
||||
from aerich.ddl.postgres import PostgresDDL
|
||||
|
||||
cls.ddl = PostgresDDL(connection)
|
||||
cls.ddl_class = await cls.load_ddl_class()
|
||||
cls.ddl = cls.ddl_class(connection)
|
||||
await cls._get_db_version(connection)
|
||||
|
||||
@classmethod
|
||||
@@ -101,24 +105,28 @@ class Migrate:
|
||||
now = datetime.now().strftime("%Y%m%d%H%M%S").replace("/", "")
|
||||
last_version_num = await cls._get_last_version_num()
|
||||
if last_version_num is None:
|
||||
return f"0_{now}_init.sql"
|
||||
version = f"{last_version_num + 1}_{now}_{name}.sql"
|
||||
return f"0_{now}_init.py"
|
||||
version = f"{last_version_num + 1}_{now}_{name}.py"
|
||||
if len(version) > MAX_VERSION_LENGTH:
|
||||
raise ValueError(f"Version name exceeds maximum length ({MAX_VERSION_LENGTH})")
|
||||
return version
|
||||
|
||||
@classmethod
|
||||
async def _generate_diff_sql(cls, name):
|
||||
async def _generate_diff_py(cls, 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(Path(cls.migrate_location, version_file))
|
||||
content = {
|
||||
"upgrade": list(dict.fromkeys(cls.upgrade_operators)),
|
||||
"downgrade": list(dict.fromkeys(cls.downgrade_operators)),
|
||||
}
|
||||
write_version_file(Path(cls.migrate_location, version), content)
|
||||
|
||||
version_file = Path(cls.migrate_location, version)
|
||||
content = MIGRATE_TEMPLATE.format(
|
||||
upgrade_sql=";\n ".join(cls.upgrade_operators) + ";",
|
||||
downgrade_sql=";\n ".join(cls.downgrade_operators) + ";",
|
||||
)
|
||||
|
||||
with open(version_file, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
return version
|
||||
|
||||
@classmethod
|
||||
@@ -137,7 +145,7 @@ class Migrate:
|
||||
if not cls.upgrade_operators:
|
||||
return ""
|
||||
|
||||
return await cls._generate_diff_sql(name)
|
||||
return await cls._generate_diff_py(name)
|
||||
|
||||
@classmethod
|
||||
def _add_operator(cls, operator: str, upgrade=True, fk_m2m_index=False):
|
||||
@@ -347,26 +355,44 @@ class Migrate:
|
||||
),
|
||||
upgrade,
|
||||
)
|
||||
if new_data_field["indexed"]:
|
||||
cls._add_operator(
|
||||
cls._add_index(
|
||||
model, {new_data_field["db_column"]}, new_data_field["unique"]
|
||||
),
|
||||
upgrade,
|
||||
True,
|
||||
)
|
||||
# remove fields
|
||||
for old_data_field_name in set(old_data_fields_name).difference(
|
||||
set(new_data_fields_name)
|
||||
):
|
||||
# don't remove field if is rename
|
||||
# don't remove field if is renamed
|
||||
if (upgrade and old_data_field_name in cls._rename_old) or (
|
||||
not upgrade and old_data_field_name in cls._rename_new
|
||||
):
|
||||
continue
|
||||
old_data_field = next(
|
||||
filter(lambda x: x.get("name") == old_data_field_name, old_data_fields)
|
||||
)
|
||||
db_column = old_data_field["db_column"]
|
||||
cls._add_operator(
|
||||
cls._remove_field(
|
||||
model,
|
||||
next(
|
||||
filter(
|
||||
lambda x: x.get("name") == old_data_field_name, old_data_fields
|
||||
)
|
||||
).get("db_column"),
|
||||
db_column,
|
||||
),
|
||||
upgrade,
|
||||
)
|
||||
if old_data_field["indexed"]:
|
||||
cls._add_operator(
|
||||
cls._drop_index(
|
||||
model,
|
||||
{db_column},
|
||||
),
|
||||
upgrade,
|
||||
True,
|
||||
)
|
||||
|
||||
old_fk_fields = old_model_describe.get("fk_fields")
|
||||
new_fk_fields = new_model_describe.get("fk_fields")
|
||||
|
||||
@@ -426,8 +452,14 @@ class Migrate:
|
||||
cls._drop_index(model, (field_name,), unique), upgrade, True
|
||||
)
|
||||
elif option == "db_field_types.":
|
||||
# continue since repeated with others
|
||||
continue
|
||||
if new_data_field.get("field_type") == "DecimalField":
|
||||
# modify column
|
||||
cls._add_operator(
|
||||
cls._modify_field(model, new_data_field),
|
||||
upgrade,
|
||||
)
|
||||
else:
|
||||
continue
|
||||
elif option == "default":
|
||||
if not (
|
||||
is_default_function(old_new[0]) or is_default_function(old_new[1])
|
||||
|
@@ -3,11 +3,12 @@ from tortoise import Model, fields
|
||||
from aerich.coder import decoder, encoder
|
||||
|
||||
MAX_VERSION_LENGTH = 255
|
||||
MAX_APP_LENGTH = 100
|
||||
|
||||
|
||||
class Aerich(Model):
|
||||
version = fields.CharField(max_length=MAX_VERSION_LENGTH)
|
||||
app = fields.CharField(max_length=20)
|
||||
app = fields.CharField(max_length=MAX_APP_LENGTH)
|
||||
content = fields.JSONField(encoder=encoder, decoder=decoder)
|
||||
|
||||
class Meta:
|
||||
|
@@ -1,9 +1,9 @@
|
||||
import importlib
|
||||
import importlib.util
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Dict, Union
|
||||
from typing import Dict
|
||||
|
||||
from click import BadOptionUsage, ClickException, Context
|
||||
from tortoise import BaseDBAsyncClient, Tortoise
|
||||
@@ -11,7 +11,7 @@ from tortoise import BaseDBAsyncClient, Tortoise
|
||||
|
||||
def add_src_path(path: str) -> str:
|
||||
"""
|
||||
add a folder to the paths so we can import from there
|
||||
add a folder to the paths, so we can import from there
|
||||
:param path: path to add
|
||||
:return: absolute path
|
||||
"""
|
||||
@@ -77,60 +77,6 @@ def get_tortoise_config(ctx: Context, tortoise_orm: str) -> dict:
|
||||
return config
|
||||
|
||||
|
||||
_UPGRADE = "-- upgrade --\n"
|
||||
_DOWNGRADE = "-- downgrade --\n"
|
||||
|
||||
|
||||
def get_version_content_from_file(version_file: Union[str, Path]) -> Dict:
|
||||
"""
|
||||
get version content
|
||||
:param version_file:
|
||||
:return:
|
||||
"""
|
||||
with open(version_file, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
first = content.index(_UPGRADE)
|
||||
try:
|
||||
second = content.index(_DOWNGRADE)
|
||||
except ValueError:
|
||||
second = len(content) - 1
|
||||
upgrade_content = content[first + len(_UPGRADE) : second].strip() # noqa:E203
|
||||
downgrade_content = content[second + len(_DOWNGRADE) :].strip() # noqa:E203
|
||||
ret = {
|
||||
"upgrade": list(filter(lambda x: x or False, upgrade_content.split(";\n"))),
|
||||
"downgrade": list(filter(lambda x: x or False, downgrade_content.split(";\n"))),
|
||||
}
|
||||
return ret
|
||||
|
||||
|
||||
def write_version_file(version_file: Path, content: Dict):
|
||||
"""
|
||||
write version file
|
||||
:param version_file:
|
||||
:param content:
|
||||
:return:
|
||||
"""
|
||||
with open(version_file, "w", encoding="utf-8") as f:
|
||||
f.write(_UPGRADE)
|
||||
upgrade = content.get("upgrade")
|
||||
if len(upgrade) > 1:
|
||||
f.write(";\n".join(upgrade))
|
||||
if not upgrade[-1].endswith(";"):
|
||||
f.write(";\n")
|
||||
else:
|
||||
f.write(f"{upgrade[0]}")
|
||||
if not upgrade[0].endswith(";"):
|
||||
f.write(";")
|
||||
f.write("\n")
|
||||
downgrade = content.get("downgrade")
|
||||
if downgrade:
|
||||
f.write(_DOWNGRADE)
|
||||
if len(downgrade) > 1:
|
||||
f.write(";\n".join(downgrade) + ";\n")
|
||||
else:
|
||||
f.write(f"{downgrade[0]};\n")
|
||||
|
||||
|
||||
def get_models_describe(app: str) -> Dict:
|
||||
"""
|
||||
get app models describe
|
||||
@@ -146,3 +92,11 @@ def get_models_describe(app: str) -> Dict:
|
||||
|
||||
def is_default_function(string: str):
|
||||
return re.match(r"^<function.+>$", str(string or ""))
|
||||
|
||||
|
||||
def import_py_file(file: Path):
|
||||
module_name, file_ext = os.path.splitext(os.path.split(file)[-1])
|
||||
spec = importlib.util.spec_from_file_location(module_name, file)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
@@ -1 +1 @@
|
||||
__version__ = "0.6.2"
|
||||
__version__ = "0.7.1"
|
||||
|
667
poetry.lock
generated
667
poetry.lock
generated
@@ -11,7 +11,7 @@ typing_extensions = ">=3.7.2"
|
||||
|
||||
[[package]]
|
||||
name = "asyncmy"
|
||||
version = "0.2.3"
|
||||
version = "0.2.5"
|
||||
description = "A fast asyncio MySQL driver"
|
||||
category = "main"
|
||||
optional = true
|
||||
@@ -19,7 +19,7 @@ python-versions = ">=3.7,<4.0"
|
||||
|
||||
[[package]]
|
||||
name = "asyncpg"
|
||||
version = "0.25.0"
|
||||
version = "0.26.0"
|
||||
description = "An asyncio PostgreSQL driver"
|
||||
category = "main"
|
||||
optional = true
|
||||
@@ -35,7 +35,7 @@ test = ["pycodestyle (>=2.7.0,<2.8.0)", "flake8 (>=3.9.2,<3.10.0)", "uvloop (>=0
|
||||
|
||||
[[package]]
|
||||
name = "atomicwrites"
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
description = "Atomic file writes."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -43,25 +43,25 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "21.4.0"
|
||||
version = "22.1.0"
|
||||
description = "Classes Without Boilerplate"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
python-versions = ">=3.5"
|
||||
|
||||
[package.extras]
|
||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
|
||||
dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
|
||||
docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"]
|
||||
tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
|
||||
tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"]
|
||||
|
||||
[[package]]
|
||||
name = "bandit"
|
||||
version = "1.7.1"
|
||||
version = "1.7.4"
|
||||
description = "Security oriented static analyser for python code."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""}
|
||||
@@ -69,36 +69,37 @@ GitPython = ">=1.0.1"
|
||||
PyYAML = ">=5.3.1"
|
||||
stevedore = ">=1.20.0"
|
||||
|
||||
[package.extras]
|
||||
test = ["coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "toml", "beautifulsoup4 (>=4.8.0)", "pylint (==1.9.4)"]
|
||||
toml = ["toml"]
|
||||
yaml = ["pyyaml"]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "21.12b0"
|
||||
version = "22.6.0"
|
||||
description = "The uncompromising code formatter."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6.2"
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=7.1.2"
|
||||
click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
pathspec = ">=0.9.0,<1"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
tomli = ">=0.2.6,<2.0.0"
|
||||
tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""}
|
||||
typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""}
|
||||
typing-extensions = [
|
||||
{version = ">=3.10.0.0", markers = "python_version < \"3.10\""},
|
||||
{version = "!=3.10.0.1", markers = "python_version >= \"3.10\""},
|
||||
]
|
||||
typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""}
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
d = ["aiohttp (>=3.7.4)"]
|
||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
python2 = ["typed-ast (>=1.4.3)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "cffi"
|
||||
version = "1.15.0"
|
||||
version = "1.15.1"
|
||||
description = "Foreign Function Interface for Python calling C code."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -109,11 +110,11 @@ pycparser = "*"
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.0.3"
|
||||
version = "8.1.3"
|
||||
description = "Composable command line interface toolkit"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
colorama = {version = "*", markers = "platform_system == \"Windows\""}
|
||||
@@ -121,7 +122,7 @@ importlib-metadata = {version = "*", markers = "python_version < \"3.8\""}
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.4"
|
||||
version = "0.4.5"
|
||||
description = "Cross-platform colored terminal text."
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -129,7 +130,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "36.0.1"
|
||||
version = "37.0.4"
|
||||
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -144,18 +145,7 @@ docstest = ["pyenchant (>=1.6.11)", "twine (>=1.12.0)", "sphinxcontrib-spelling
|
||||
pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"]
|
||||
sdist = ["setuptools_rust (>=0.11.4)"]
|
||||
ssh = ["bcrypt (>=3.1.5)"]
|
||||
test = ["pytest (>=6.2.0)", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "ddlparse"
|
||||
version = "1.10.0"
|
||||
description = "DDL parase and Convert to BigQuery JSON schema"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
pyparsing = "*"
|
||||
test = ["pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pretend", "iso8601", "pytz", "hypothesis (>=1.11.4,!=3.79.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "dictdiffer"
|
||||
@@ -166,10 +156,10 @@ optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.extras]
|
||||
all = ["Sphinx (>=3)", "sphinx-rtd-theme (>=0.2)", "check-manifest (>=0.42)", "mock (>=1.3.0)", "pytest-cov (>=2.10.1)", "pytest-isort (>=1.2.0)", "sphinx (>=3)", "tox (>=3.7.0)", "numpy (>=1.13.0)", "numpy (>=1.15.0)", "numpy (>=1.18.0)", "pytest (==5.4.3)", "pytest-pycodestyle (>=2)", "pytest-pydocstyle (>=2)", "pytest (>=6)", "pytest-pycodestyle (>=2.2.0)", "pytest-pydocstyle (>=2.2.0)", "numpy (>=1.20.0)"]
|
||||
docs = ["Sphinx (>=3)", "sphinx-rtd-theme (>=0.2)"]
|
||||
numpy = ["numpy (>=1.13.0)", "numpy (>=1.15.0)", "numpy (>=1.18.0)", "numpy (>=1.20.0)"]
|
||||
tests = ["check-manifest (>=0.42)", "mock (>=1.3.0)", "pytest-cov (>=2.10.1)", "pytest-isort (>=1.2.0)", "sphinx (>=3)", "tox (>=3.7.0)", "pytest (==5.4.3)", "pytest-pycodestyle (>=2)", "pytest-pydocstyle (>=2)", "pytest (>=6)", "pytest-pycodestyle (>=2.2.0)", "pytest-pydocstyle (>=2.2.0)"]
|
||||
tests = ["pytest-pydocstyle (>=2.2.0)", "pytest-pycodestyle (>=2.2.0)", "pytest (>=6)", "pytest-pydocstyle (>=2)", "pytest-pycodestyle (>=2)", "pytest (==5.4.3)", "tox (>=3.7.0)", "sphinx (>=3)", "pytest-isort (>=1.2.0)", "pytest-cov (>=2.10.1)", "mock (>=1.3.0)", "check-manifest (>=0.42)"]
|
||||
numpy = ["numpy (>=1.20.0)", "numpy (>=1.18.0)", "numpy (>=1.15.0)", "numpy (>=1.13.0)"]
|
||||
docs = ["sphinx-rtd-theme (>=0.2)", "Sphinx (>=3)"]
|
||||
all = ["numpy (>=1.20.0)", "pytest-pydocstyle (>=2.2.0)", "pytest-pycodestyle (>=2.2.0)", "pytest (>=6)", "pytest-pydocstyle (>=2)", "pytest-pycodestyle (>=2)", "pytest (==5.4.3)", "numpy (>=1.18.0)", "numpy (>=1.15.0)", "numpy (>=1.13.0)", "tox (>=3.7.0)", "sphinx (>=3)", "pytest-isort (>=1.2.0)", "pytest-cov (>=2.10.1)", "mock (>=1.3.0)", "check-manifest (>=0.42)", "sphinx-rtd-theme (>=0.2)", "Sphinx (>=3)"]
|
||||
|
||||
[[package]]
|
||||
name = "execnet"
|
||||
@@ -209,7 +199,7 @@ smmap = ">=3.0.1,<6"
|
||||
|
||||
[[package]]
|
||||
name = "gitpython"
|
||||
version = "3.1.26"
|
||||
version = "3.1.27"
|
||||
description = "GitPython is a python library used to interact with Git repositories"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -245,11 +235,11 @@ python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "iso8601"
|
||||
version = "0.1.16"
|
||||
version = "1.0.2"
|
||||
description = "Simple module to parse ISO 8601 dates"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
python-versions = ">=3.6.2,<4.0"
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
@@ -302,7 +292,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7"
|
||||
|
||||
[[package]]
|
||||
name = "pbr"
|
||||
version = "5.8.0"
|
||||
version = "5.10.0"
|
||||
description = "Python Build Reasonableness"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -310,15 +300,15 @@ python-versions = ">=2.6"
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "2.4.1"
|
||||
version = "2.5.2"
|
||||
description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"]
|
||||
docs = ["furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)", "sphinx (>=4)"]
|
||||
test = ["appdirs (==1.4.4)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)", "pytest (>=6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
@@ -332,8 +322,8 @@ python-versions = ">=3.6"
|
||||
importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""}
|
||||
|
||||
[package.extras]
|
||||
dev = ["pre-commit", "tox"]
|
||||
testing = ["pytest", "pytest-benchmark"]
|
||||
testing = ["pytest-benchmark", "pytest"]
|
||||
dev = ["tox", "pre-commit"]
|
||||
|
||||
[[package]]
|
||||
name = "py"
|
||||
@@ -359,6 +349,21 @@ category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "1.9.2"
|
||||
description = "Data validation and settings management using python type hints"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6.1"
|
||||
|
||||
[package.dependencies]
|
||||
typing-extensions = ">=3.7.4.3"
|
||||
|
||||
[package.extras]
|
||||
dotenv = ["python-dotenv (>=0.10.4)"]
|
||||
email = ["email-validator (>=1.0.3)"]
|
||||
|
||||
[[package]]
|
||||
name = "pyflakes"
|
||||
version = "2.4.0"
|
||||
@@ -369,30 +374,42 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "pyparsing"
|
||||
version = "3.0.6"
|
||||
description = "Python parsing module"
|
||||
category = "main"
|
||||
version = "3.0.9"
|
||||
description = "pyparsing module - Classes and methods to define and execute parsing grammars"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.6.8"
|
||||
|
||||
[package.extras]
|
||||
diagrams = ["jinja2", "railroad-diagrams"]
|
||||
diagrams = ["railroad-diagrams", "jinja2"]
|
||||
|
||||
[[package]]
|
||||
name = "pypika-tortoise"
|
||||
version = "0.1.3"
|
||||
version = "0.1.6"
|
||||
description = "Forked from pypika and streamline just for tortoise-orm"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7,<4.0"
|
||||
|
||||
[[package]]
|
||||
name = "pyproject-flake8"
|
||||
version = "0.0.1a5"
|
||||
description = "pyproject-flake8 (`pflake8`), a monkey patching wrapper to connect flake8 with pyproject.toml configuration"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[package.dependencies]
|
||||
flake8 = "<5.0.0"
|
||||
tomli = {version = "*", markers = "python_version < \"3.11\""}
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "6.2.5"
|
||||
version = "7.1.2"
|
||||
description = "pytest: simple powerful testing with Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
|
||||
@@ -403,14 +420,14 @@ iniconfig = "*"
|
||||
packaging = "*"
|
||||
pluggy = ">=0.12,<2.0"
|
||||
py = ">=1.8.2"
|
||||
toml = "*"
|
||||
tomli = ">=1.0.0"
|
||||
|
||||
[package.extras]
|
||||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
|
||||
testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-asyncio"
|
||||
version = "0.17.1"
|
||||
version = "0.19.0"
|
||||
description = "Pytest support for asyncio"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -418,10 +435,10 @@ python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=6.1.0"
|
||||
typing-extensions = ">=4.0"
|
||||
typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""}
|
||||
|
||||
[package.extras]
|
||||
testing = ["coverage (==6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)", "mypy (==0.931)"]
|
||||
testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)", "flaky (>=3.5.0)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-forked"
|
||||
@@ -437,11 +454,11 @@ pytest = ">=3.10"
|
||||
|
||||
[[package]]
|
||||
name = "pytest-mock"
|
||||
version = "3.6.1"
|
||||
version = "3.8.2"
|
||||
description = "Thin-wrapper around the mock package for easier use with pytest"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.dependencies]
|
||||
pytest = ">=5.0"
|
||||
@@ -469,7 +486,7 @@ testing = ["filelock"]
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2021.3"
|
||||
version = "2022.2.1"
|
||||
description = "World timezone definitions, modern and historical"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -503,25 +520,17 @@ python-versions = ">=3.6"
|
||||
importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""}
|
||||
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.10.2"
|
||||
description = "Python Library for Tom's Obvious, Minimal Language"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "1.2.3"
|
||||
version = "2.0.1"
|
||||
description = "A lil' TOML parser"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "tomlkit"
|
||||
version = "0.8.0"
|
||||
version = "0.11.4"
|
||||
description = "Style preserving TOML library"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -529,7 +538,7 @@ python-versions = ">=3.6,<4.0"
|
||||
|
||||
[[package]]
|
||||
name = "tortoise-orm"
|
||||
version = "0.18.1"
|
||||
version = "0.19.2"
|
||||
description = "Easy async ORM for python, built with relations in mind"
|
||||
category = "main"
|
||||
optional = false
|
||||
@@ -537,19 +546,21 @@ python-versions = ">=3.7,<4.0"
|
||||
|
||||
[package.dependencies]
|
||||
aiosqlite = ">=0.16.0,<0.18.0"
|
||||
iso8601 = ">=0.1.13,<0.2.0"
|
||||
pypika-tortoise = ">=0.1.3,<0.2.0"
|
||||
iso8601 = ">=1.0.2,<2.0.0"
|
||||
pypika-tortoise = ">=0.1.6,<0.2.0"
|
||||
pytz = "*"
|
||||
|
||||
[package.extras]
|
||||
aiomysql = ["aiomysql"]
|
||||
asyncmy = ["asyncmy"]
|
||||
asyncmy = ["asyncmy (>=0.2.5,<0.3.0)"]
|
||||
asyncodbc = ["asyncodbc (>=0.1.1,<0.2.0)"]
|
||||
asyncpg = ["asyncpg"]
|
||||
accel = ["ciso8601", "orjson", "uvloop"]
|
||||
psycopg = ["psycopg"]
|
||||
|
||||
[[package]]
|
||||
name = "typed-ast"
|
||||
version = "1.5.1"
|
||||
version = "1.5.4"
|
||||
description = "a fork of Python 2 and 3 ast modules with type comment support"
|
||||
category = "dev"
|
||||
optional = false
|
||||
@@ -557,23 +568,23 @@ python-versions = ">=3.6"
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.0.1"
|
||||
description = "Backported and Experimental Type Hints for Python 3.6+"
|
||||
version = "4.3.0"
|
||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.7.0"
|
||||
version = "3.8.1"
|
||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
|
||||
[package.extras]
|
||||
docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"]
|
||||
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"]
|
||||
docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"]
|
||||
testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
|
||||
|
||||
[extras]
|
||||
asyncmy = ["asyncmy"]
|
||||
@@ -582,305 +593,193 @@ asyncpg = ["asyncpg"]
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.7"
|
||||
content-hash = "972c0d0a1eb0c6a697ccbce550af36e1bb43cb0d74b7819f80846f5599bb8c2b"
|
||||
content-hash = "37c6a73133abae4ce337962636160ae207f38b301b34ecfb6cb2547c3a25be3e"
|
||||
|
||||
[metadata.files]
|
||||
aiosqlite = [
|
||||
{file = "aiosqlite-0.17.0-py3-none-any.whl", hash = "sha256:6c49dc6d3405929b1d08eeccc72306d3677503cc5e5e43771efc1e00232e8231"},
|
||||
{file = "aiosqlite-0.17.0.tar.gz", hash = "sha256:f0e6acc24bc4864149267ac82fb46dfb3be4455f99fe21df82609cc6e6baee51"},
|
||||
]
|
||||
asyncmy = [
|
||||
{file = "asyncmy-0.2.3-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:c9dc38b56e3091d75ccda1ed598f90dac0489f4e6700bb3aae89b9a8b4635ad3"},
|
||||
{file = "asyncmy-0.2.3-cp310-cp310-manylinux_2_31_x86_64.whl", hash = "sha256:38d6c2e658d13213ced685b5e41e35df1122174423b38f2bc27a6a4535de05b2"},
|
||||
{file = "asyncmy-0.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:2b6dbfe7f4f7ffbcaa190f477f79361cbbc79248eeb05ee8c338b295b18a0119"},
|
||||
{file = "asyncmy-0.2.3-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:28a534ceab5fbc2e20a29b2167c05c94f2cc1e2735a96fcc24b684890bb1109a"},
|
||||
{file = "asyncmy-0.2.3-cp37-cp37m-manylinux_2_31_x86_64.whl", hash = "sha256:0c7db0d0b7c0f47fcb656c1db41f5845b3a5e7e83013264c83e943e53c4abb60"},
|
||||
{file = "asyncmy-0.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:22ab5de34356a7331443d0076c47c78aedd3b1c41e1b6baf4017b2f207fd39d4"},
|
||||
{file = "asyncmy-0.2.3-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:2b14ebd0c1e050a6ee0a314111527327fdb53fe490169af6ed9361a921fba2fa"},
|
||||
{file = "asyncmy-0.2.3-cp38-cp38-manylinux_2_31_x86_64.whl", hash = "sha256:ef785957e480902d9b1a34f23e29157de84606bf758ddbfbabc1afe93f91ece3"},
|
||||
{file = "asyncmy-0.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:804fda2c96e16de5b4a7740a49cf21207fe6b856875608f28a75a486e4903b3d"},
|
||||
{file = "asyncmy-0.2.3-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4be0f01f79974adf7c064c3c23bd30cd24627c081a39a03461bd4fea0a59562b"},
|
||||
{file = "asyncmy-0.2.3-cp39-cp39-manylinux_2_31_x86_64.whl", hash = "sha256:3167337d2e778b560fc109ec9d388562b4e9b0241e6d31ca2de15bf7437c781d"},
|
||||
{file = "asyncmy-0.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:5577b695c38e01377e7ef4f5bd3877aada11d1174f80b6354be55a5447f9d1f8"},
|
||||
{file = "asyncmy-0.2.3.tar.gz", hash = "sha256:769f749d8b03b28a31b185b77c54e8f8f363ee8a3c3719bad8a71e4e9a0ce8a6"},
|
||||
]
|
||||
aiosqlite = []
|
||||
asyncmy = []
|
||||
asyncpg = [
|
||||
{file = "asyncpg-0.25.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf5e3408a14a17d480f36ebaf0401a12ff6ae5457fdf45e4e2775c51cc9517d3"},
|
||||
{file = "asyncpg-0.25.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2bc197fc4aca2fd24f60241057998124012469d2e414aed3f992579db0c88e3a"},
|
||||
{file = "asyncpg-0.25.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1a70783f6ffa34cc7dd2de20a873181414a34fd35a4a208a1f1a7f9f695e4ec4"},
|
||||
{file = "asyncpg-0.25.0-cp310-cp310-win32.whl", hash = "sha256:43cde84e996a3afe75f325a68300093425c2f47d340c0fc8912765cf24a1c095"},
|
||||
{file = "asyncpg-0.25.0-cp310-cp310-win_amd64.whl", hash = "sha256:56d88d7ef4341412cd9c68efba323a4519c916979ba91b95d4c08799d2ff0c09"},
|
||||
{file = "asyncpg-0.25.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a84d30e6f850bac0876990bcd207362778e2208df0bee8be8da9f1558255e634"},
|
||||
{file = "asyncpg-0.25.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:beaecc52ad39614f6ca2e48c3ca15d56e24a2c15cbfdcb764a4320cc45f02fd5"},
|
||||
{file = "asyncpg-0.25.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:6f8f5fc975246eda83da8031a14004b9197f510c41511018e7b1bedde6968e92"},
|
||||
{file = "asyncpg-0.25.0-cp36-cp36m-win32.whl", hash = "sha256:ddb4c3263a8d63dcde3d2c4ac1c25206bfeb31fa83bd70fd539e10f87739dee4"},
|
||||
{file = "asyncpg-0.25.0-cp36-cp36m-win_amd64.whl", hash = "sha256:bf6dc9b55b9113f39eaa2057337ce3f9ef7de99a053b8a16360395ce588925cd"},
|
||||
{file = "asyncpg-0.25.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:acb311722352152936e58a8ee3c5b8e791b24e84cd7d777c414ff05b3530ca68"},
|
||||
{file = "asyncpg-0.25.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0a61fb196ce4dae2f2fa26eb20a778db21bbee484d2e798cb3cc988de13bdd1b"},
|
||||
{file = "asyncpg-0.25.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2633331cbc8429030b4f20f712f8d0fbba57fa8555ee9b2f45f981b81328b256"},
|
||||
{file = "asyncpg-0.25.0-cp37-cp37m-win32.whl", hash = "sha256:863d36eba4a7caa853fd7d83fad5fd5306f050cc2fe6e54fbe10cdb30420e5e9"},
|
||||
{file = "asyncpg-0.25.0-cp37-cp37m-win_amd64.whl", hash = "sha256:fe471ccd915b739ca65e2e4dbd92a11b44a5b37f2e38f70827a1c147dafe0fa8"},
|
||||
{file = "asyncpg-0.25.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:72a1e12ea0cf7c1e02794b697e3ca967b2360eaa2ce5d4bfdd8604ec2d6b774b"},
|
||||
{file = "asyncpg-0.25.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4327f691b1bdb222df27841938b3e04c14068166b3a97491bec2cb982f49f03e"},
|
||||
{file = "asyncpg-0.25.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:739bbd7f89a2b2f6bc44cb8bf967dab12c5bc714fcbe96e68d512be45ecdf962"},
|
||||
{file = "asyncpg-0.25.0-cp38-cp38-win32.whl", hash = "sha256:18d49e2d93a7139a2fdbd113e320cc47075049997268a61bfbe0dde680c55471"},
|
||||
{file = "asyncpg-0.25.0-cp38-cp38-win_amd64.whl", hash = "sha256:191fe6341385b7fdea7dbdcf47fd6db3fd198827dcc1f2b228476d13c05a03c6"},
|
||||
{file = "asyncpg-0.25.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:52fab7f1b2c29e187dd8781fce896249500cf055b63471ad66332e537e9b5f7e"},
|
||||
{file = "asyncpg-0.25.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a738f1b2876f30d710d3dc1e7858160a0afe1603ba16bf5f391f5316eb0ed855"},
|
||||
{file = "asyncpg-0.25.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5e4105f57ad1e8fbc8b1e535d8fcefa6ce6c71081228f08680c6dea24384ff0e"},
|
||||
{file = "asyncpg-0.25.0-cp39-cp39-win32.whl", hash = "sha256:f55918ded7b85723a5eaeb34e86e7b9280d4474be67df853ab5a7fa0cc7c6bf2"},
|
||||
{file = "asyncpg-0.25.0-cp39-cp39-win_amd64.whl", hash = "sha256:649e2966d98cc48d0646d9a4e29abecd8b59d38d55c256d5c857f6b27b7407ac"},
|
||||
{file = "asyncpg-0.25.0.tar.gz", hash = "sha256:63f8e6a69733b285497c2855464a34de657f2cccd25aeaeeb5071872e9382540"},
|
||||
]
|
||||
atomicwrites = [
|
||||
{file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"},
|
||||
{file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"},
|
||||
]
|
||||
attrs = [
|
||||
{file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"},
|
||||
{file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"},
|
||||
{file = "asyncpg-0.26.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ed3880b3aec8bda90548218fe0914d251d641f798382eda39a17abfc4910af0"},
|
||||
{file = "asyncpg-0.26.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5bd99ee7a00e87df97b804f178f31086e88c8106aca9703b1d7be5078999e68"},
|
||||
{file = "asyncpg-0.26.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:868a71704262834065ca7113d80b1f679609e2df77d837747e3d92150dd5a39b"},
|
||||
{file = "asyncpg-0.26.0-cp310-cp310-win32.whl", hash = "sha256:838e4acd72da370ad07243898e886e93d3c0c9413f4444d600ba60a5cc206014"},
|
||||
{file = "asyncpg-0.26.0-cp310-cp310-win_amd64.whl", hash = "sha256:a254d09a3a989cc1839ba2c34448b879cdd017b528a0cda142c92fbb6c13d957"},
|
||||
{file = "asyncpg-0.26.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3ecbe8ed3af4c739addbfbd78f7752866cce2c4e9cc3f953556e4960349ae360"},
|
||||
{file = "asyncpg-0.26.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ce7d8c0ab4639bbf872439eba86ef62dd030b245ad0e17c8c675d93d7a6b2d"},
|
||||
{file = "asyncpg-0.26.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7129bd809990fd119e8b2b9982e80be7712bb6041cd082be3e415e60e5e2e98f"},
|
||||
{file = "asyncpg-0.26.0-cp36-cp36m-win32.whl", hash = "sha256:03f44926fa7ff7ccd59e98f05c7e227e9de15332a7da5bbcef3654bf468ee597"},
|
||||
{file = "asyncpg-0.26.0-cp36-cp36m-win_amd64.whl", hash = "sha256:b1f7b173af649b85126429e11a628d01a5b75973d2a55d64dba19ad8f0e9f904"},
|
||||
{file = "asyncpg-0.26.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efe056fd22fc6ed5c1ab353b6510808409566daac4e6f105e2043797f17b8dad"},
|
||||
{file = "asyncpg-0.26.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d96cf93e01df9fb03cef5f62346587805e6c0ca6f654c23b8d35315bdc69af59"},
|
||||
{file = "asyncpg-0.26.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:235205b60d4d014921f7b1cdca0e19669a9a8978f7606b3eb8237ca95f8e716e"},
|
||||
{file = "asyncpg-0.26.0-cp37-cp37m-win32.whl", hash = "sha256:0de408626cfc811ef04f372debfcdd5e4ab5aeb358f2ff14d1bdc246ed6272b5"},
|
||||
{file = "asyncpg-0.26.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f92d501bf213b16fabad4fbb0061398d2bceae30ddc228e7314c28dcc6641b79"},
|
||||
{file = "asyncpg-0.26.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9acb22a7b6bcca0d80982dce3d67f267d43e960544fb5dd934fd3abe20c48014"},
|
||||
{file = "asyncpg-0.26.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e550d8185f2c4725c1e8d3c555fe668b41bd092143012ddcc5343889e1c2a13d"},
|
||||
{file = "asyncpg-0.26.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:050e339694f8c5d9aebcf326ca26f6622ef23963a6a3a4f97aeefc743954afd5"},
|
||||
{file = "asyncpg-0.26.0-cp38-cp38-win32.whl", hash = "sha256:b0c3f39ebfac06848ba3f1e280cb1fada7cc1229538e3dad3146e8d1f9deb92a"},
|
||||
{file = "asyncpg-0.26.0-cp38-cp38-win_amd64.whl", hash = "sha256:49fc7220334cc31d14866a0b77a575d6a5945c0fa3bb67f17304e8b838e2a02b"},
|
||||
{file = "asyncpg-0.26.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d156e53b329e187e2dbfca8c28c999210045c45ef22a200b50de9b9e520c2694"},
|
||||
{file = "asyncpg-0.26.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b4051012ca75defa9a1dc6b78185ca58cdc3a247187eb76a6bcf55dfaa2fad4"},
|
||||
{file = "asyncpg-0.26.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6d60f15a0ac18c54a6ca6507c28599c06e2e87a0901e7b548f15243d71905b18"},
|
||||
{file = "asyncpg-0.26.0-cp39-cp39-win32.whl", hash = "sha256:ede1a3a2c377fe12a3930f4b4dd5340e8b32929541d5db027a21816852723438"},
|
||||
{file = "asyncpg-0.26.0-cp39-cp39-win_amd64.whl", hash = "sha256:8e1e79f0253cbd51fc43c4d0ce8804e46ee71f6c173fdc75606662ad18756b52"},
|
||||
{file = "asyncpg-0.26.0.tar.gz", hash = "sha256:77e684a24fee17ba3e487ca982d0259ed17bae1af68006f4cf284b23ba20ea2c"},
|
||||
]
|
||||
atomicwrites = []
|
||||
attrs = []
|
||||
bandit = [
|
||||
{file = "bandit-1.7.1-py3-none-any.whl", hash = "sha256:f5acd838e59c038a159b5c621cf0f8270b279e884eadd7b782d7491c02add0d4"},
|
||||
{file = "bandit-1.7.1.tar.gz", hash = "sha256:a81b00b5436e6880fa8ad6799bc830e02032047713cbb143a12939ac67eb756c"},
|
||||
]
|
||||
black = [
|
||||
{file = "black-21.12b0-py3-none-any.whl", hash = "sha256:a615e69ae185e08fdd73e4715e260e2479c861b5740057fde6e8b4e3b7dd589f"},
|
||||
{file = "black-21.12b0.tar.gz", hash = "sha256:77b80f693a569e2e527958459634f18df9b0ba2625ba4e0c2d5da5be42e6f2b3"},
|
||||
{file = "bandit-1.7.4-py3-none-any.whl", hash = "sha256:412d3f259dab4077d0e7f0c11f50f650cc7d10db905d98f6520a95a18049658a"},
|
||||
{file = "bandit-1.7.4.tar.gz", hash = "sha256:2d63a8c573417bae338962d4b9b06fbc6080f74ecd955a092849e1e65c717bd2"},
|
||||
]
|
||||
black = []
|
||||
cffi = [
|
||||
{file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"},
|
||||
{file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"},
|
||||
{file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"},
|
||||
{file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"},
|
||||
{file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"},
|
||||
{file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"},
|
||||
{file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"},
|
||||
{file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"},
|
||||
{file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"},
|
||||
{file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"},
|
||||
{file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"},
|
||||
{file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"},
|
||||
{file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"},
|
||||
]
|
||||
click = [
|
||||
{file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"},
|
||||
{file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"},
|
||||
]
|
||||
colorama = [
|
||||
{file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"},
|
||||
{file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"},
|
||||
{file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"},
|
||||
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"},
|
||||
{file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"},
|
||||
{file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"},
|
||||
{file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"},
|
||||
{file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"},
|
||||
{file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"},
|
||||
{file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
|
||||
{file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
|
||||
{file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
|
||||
]
|
||||
click = []
|
||||
colorama = []
|
||||
cryptography = [
|
||||
{file = "cryptography-36.0.1-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:73bc2d3f2444bcfeac67dd130ff2ea598ea5f20b40e36d19821b4df8c9c5037b"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:2d87cdcb378d3cfed944dac30596da1968f88fb96d7fc34fdae30a99054b2e31"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74d6c7e80609c0f4c2434b97b80c7f8fdfaa072ca4baab7e239a15d6d70ed73a"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:6c0c021f35b421ebf5976abf2daacc47e235f8b6082d3396a2fe3ccd537ab173"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59a9d55027a8b88fd9fd2826c4392bd487d74bf628bb9d39beecc62a644c12"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0a817b961b46894c5ca8a66b599c745b9a3d9f822725221f0e0fe49dc043a3a3"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:94ae132f0e40fe48f310bba63f477f14a43116f05ddb69d6fa31e93f05848ae2"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:7be0eec337359c155df191d6ae00a5e8bbb63933883f4f5dffc439dac5348c3f"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:e0344c14c9cb89e76eb6a060e67980c9e35b3f36691e15e1b7a9e58a0a6c6dc3"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-win32.whl", hash = "sha256:4caa4b893d8fad33cf1964d3e51842cd78ba87401ab1d2e44556826df849a8ca"},
|
||||
{file = "cryptography-36.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:391432971a66cfaf94b21c24ab465a4cc3e8bf4a939c1ca5c3e3a6e0abebdbcf"},
|
||||
{file = "cryptography-36.0.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb5829d027ff82aa872d76158919045a7c1e91fbf241aec32cb07956e9ebd3c9"},
|
||||
{file = "cryptography-36.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc15b1c22e55c4d5566e3ca4db8689470a0ca2babef8e3a9ee057a8b82ce4b1"},
|
||||
{file = "cryptography-36.0.1-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:596f3cd67e1b950bc372c33f1a28a0692080625592ea6392987dba7f09f17a94"},
|
||||
{file = "cryptography-36.0.1-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:30ee1eb3ebe1644d1c3f183d115a8c04e4e603ed6ce8e394ed39eea4a98469ac"},
|
||||
{file = "cryptography-36.0.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ec63da4e7e4a5f924b90af42eddf20b698a70e58d86a72d943857c4c6045b3ee"},
|
||||
{file = "cryptography-36.0.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca238ceb7ba0bdf6ce88c1b74a87bffcee5afbfa1e41e173b1ceb095b39add46"},
|
||||
{file = "cryptography-36.0.1-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:ca28641954f767f9822c24e927ad894d45d5a1e501767599647259cbf030b903"},
|
||||
{file = "cryptography-36.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:39bdf8e70eee6b1c7b289ec6e5d84d49a6bfa11f8b8646b5b3dfe41219153316"},
|
||||
{file = "cryptography-36.0.1.tar.gz", hash = "sha256:53e5c1dc3d7a953de055d77bef2ff607ceef7a2aac0353b5d630ab67f7423638"},
|
||||
]
|
||||
ddlparse = [
|
||||
{file = "ddlparse-1.10.0-py3-none-any.whl", hash = "sha256:71761b3457c8720853af3aeef266e2da1b6edef50936969492d586d7046a2ac2"},
|
||||
{file = "ddlparse-1.10.0.tar.gz", hash = "sha256:6418681baa848eb01251ab79eb3d0ad7e140e6ab1deaae5a019353ddb3a908da"},
|
||||
]
|
||||
dictdiffer = [
|
||||
{file = "dictdiffer-0.9.0-py2.py3-none-any.whl", hash = "sha256:442bfc693cfcadaf46674575d2eba1c53b42f5e404218ca2c2ff549f2df56595"},
|
||||
{file = "dictdiffer-0.9.0.tar.gz", hash = "sha256:17bacf5fbfe613ccf1b6d512bd766e6b21fb798822a133aa86098b8ac9997578"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:549153378611c0cca1042f20fd9c5030d37a72f634c9326e225c9f666d472884"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:a958c52505c8adf0d3822703078580d2c0456dd1d27fabfb6f76fe63d2971cd6"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f721d1885ecae9078c3f6bbe8a88bc0786b6e749bf32ccec1ef2b18929a05046"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:3d41b965b3380f10e4611dbae366f6dc3cefc7c9ac4e8842a806b9672ae9add5"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80f49023dd13ba35f7c34072fa17f604d2f19bf0989f292cedf7ab5770b87a0b"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2dcb0b3b63afb6df7fd94ec6fbddac81b5492513f7b0436210d390c14d46ee8"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:b7f8dd0d4c1f21759695c05a5ec8536c12f31611541f8904083f3dc582604280"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:30788e070800fec9bbcf9faa71ea6d8068f5136f60029759fd8c3efec3c9dcb3"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:190f82f3e87033821828f60787cfa42bff98404483577b591429ed99bed39d59"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-win32.whl", hash = "sha256:b62439d7cd1222f3da897e9a9fe53bbf5c104fff4d60893ad1355d4c14a24157"},
|
||||
{file = "cryptography-37.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:f7a6de3e98771e183645181b3627e2563dcde3ce94a9e42a3f427d2255190327"},
|
||||
{file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc95ed67b6741b2607298f9ea4932ff157e570ef456ef7ff0ef4884a134cc4b"},
|
||||
{file = "cryptography-37.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:f8c0a6e9e1dd3eb0414ba320f85da6b0dcbd543126e30fcc546e7372a7fbf3b9"},
|
||||
{file = "cryptography-37.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:e007f052ed10cc316df59bc90fbb7ff7950d7e2919c9757fd42a2b8ecf8a5f67"},
|
||||
{file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bc997818309f56c0038a33b8da5c0bfbb3f1f067f315f9abd6fc07ad359398d"},
|
||||
{file = "cryptography-37.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:d204833f3c8a33bbe11eda63a54b1aad7aa7456ed769a982f21ec599ba5fa282"},
|
||||
{file = "cryptography-37.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:75976c217f10d48a8b5a8de3d70c454c249e4b91851f6838a4e48b8f41eb71aa"},
|
||||
{file = "cryptography-37.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:7099a8d55cd49b737ffc99c17de504f2257e3787e02abe6d1a6d136574873441"},
|
||||
{file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2be53f9f5505673eeda5f2736bea736c40f051a739bfae2f92d18aed1eb54596"},
|
||||
{file = "cryptography-37.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:91ce48d35f4e3d3f1d83e29ef4a9267246e6a3be51864a5b7d2247d5086fa99a"},
|
||||
{file = "cryptography-37.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4c590ec31550a724ef893c50f9a97a0c14e9c851c85621c5650d699a7b88f7ab"},
|
||||
{file = "cryptography-37.0.4.tar.gz", hash = "sha256:63f9c17c0e2474ccbebc9302ce2f07b55b3b3fcb211ded18a42d5764f5c10a82"},
|
||||
]
|
||||
dictdiffer = []
|
||||
execnet = [
|
||||
{file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"},
|
||||
{file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"},
|
||||
]
|
||||
flake8 = [
|
||||
{file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"},
|
||||
{file = "flake8-4.0.1.tar.gz", hash = "sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d"},
|
||||
]
|
||||
flake8 = []
|
||||
gitdb = [
|
||||
{file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"},
|
||||
{file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"},
|
||||
]
|
||||
gitpython = [
|
||||
{file = "GitPython-3.1.26-py3-none-any.whl", hash = "sha256:26ac35c212d1f7b16036361ca5cff3ec66e11753a0d677fb6c48fa4e1a9dd8d6"},
|
||||
{file = "GitPython-3.1.26.tar.gz", hash = "sha256:fc8868f63a2e6d268fb25f481995ba185a85a66fcad126f039323ff6635669ee"},
|
||||
{file = "GitPython-3.1.27-py3-none-any.whl", hash = "sha256:5b68b000463593e05ff2b261acff0ff0972df8ab1b70d3cdbd41b546c8b8fc3d"},
|
||||
{file = "GitPython-3.1.27.tar.gz", hash = "sha256:1c885ce809e8ba2d88a29befeb385fcea06338d3640712b59ca623c220bb5704"},
|
||||
]
|
||||
importlib-metadata = [
|
||||
{file = "importlib_metadata-4.2.0-py3-none-any.whl", hash = "sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b"},
|
||||
{file = "importlib_metadata-4.2.0.tar.gz", hash = "sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31"},
|
||||
]
|
||||
iniconfig = [
|
||||
{file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
|
||||
{file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
|
||||
]
|
||||
iso8601 = [
|
||||
{file = "iso8601-0.1.16-py2.py3-none-any.whl", hash = "sha256:906714829fedbc89955d52806c903f2332e3948ed94e31e85037f9e0226b8376"},
|
||||
{file = "iso8601-0.1.16.tar.gz", hash = "sha256:36532f77cc800594e8f16641edae7f1baf7932f05d8e508545b95fc53c6dc85b"},
|
||||
]
|
||||
isort = [
|
||||
{file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"},
|
||||
{file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"},
|
||||
]
|
||||
mccabe = [
|
||||
{file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"},
|
||||
{file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"},
|
||||
]
|
||||
mypy-extensions = [
|
||||
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
|
||||
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
|
||||
]
|
||||
packaging = [
|
||||
{file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
|
||||
{file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
|
||||
]
|
||||
pathspec = [
|
||||
{file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"},
|
||||
{file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"},
|
||||
]
|
||||
iniconfig = []
|
||||
iso8601 = []
|
||||
isort = []
|
||||
mccabe = []
|
||||
mypy-extensions = []
|
||||
packaging = []
|
||||
pathspec = []
|
||||
pbr = [
|
||||
{file = "pbr-5.8.0-py2.py3-none-any.whl", hash = "sha256:176e8560eaf61e127817ef93d8a844803abb27a4d4637f0ff3bb783129be2e0a"},
|
||||
{file = "pbr-5.8.0.tar.gz", hash = "sha256:672d8ebee84921862110f23fcec2acea191ef58543d34dfe9ef3d9f13c31cddf"},
|
||||
]
|
||||
platformdirs = [
|
||||
{file = "platformdirs-2.4.1-py3-none-any.whl", hash = "sha256:1d7385c7db91728b83efd0ca99a5afb296cab9d0ed8313a45ed8ba17967ecfca"},
|
||||
{file = "platformdirs-2.4.1.tar.gz", hash = "sha256:440633ddfebcc36264232365d7840a970e75e1018d15b4327d11f91909045fda"},
|
||||
]
|
||||
pluggy = [
|
||||
{file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
|
||||
{file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
|
||||
]
|
||||
py = [
|
||||
{file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
|
||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||
]
|
||||
pycodestyle = [
|
||||
{file = "pycodestyle-2.8.0-py2.py3-none-any.whl", hash = "sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20"},
|
||||
{file = "pycodestyle-2.8.0.tar.gz", hash = "sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f"},
|
||||
{file = "pbr-5.10.0-py2.py3-none-any.whl", hash = "sha256:da3e18aac0a3c003e9eea1a81bd23e5a3a75d745670dcf736317b7d966887fdf"},
|
||||
{file = "pbr-5.10.0.tar.gz", hash = "sha256:cfcc4ff8e698256fc17ea3ff796478b050852585aa5bae79ecd05b2ab7b39b9a"},
|
||||
]
|
||||
platformdirs = []
|
||||
pluggy = []
|
||||
py = []
|
||||
pycodestyle = []
|
||||
pycparser = [
|
||||
{file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
|
||||
{file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
|
||||
]
|
||||
pyflakes = [
|
||||
{file = "pyflakes-2.4.0-py2.py3-none-any.whl", hash = "sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e"},
|
||||
{file = "pyflakes-2.4.0.tar.gz", hash = "sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c"},
|
||||
]
|
||||
pyparsing = [
|
||||
{file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"},
|
||||
{file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"},
|
||||
]
|
||||
pypika-tortoise = [
|
||||
{file = "pypika-tortoise-0.1.3.tar.gz", hash = "sha256:ecdf2d6e0aeb0e15880d9e2ead41362ec7320f37fb25a3a71664c2e1105ad218"},
|
||||
{file = "pypika_tortoise-0.1.3-py3-none-any.whl", hash = "sha256:28fb2715a94ff2f3bc1c4ef6cc46c385c244c27d100aac760231bf612361d5ba"},
|
||||
]
|
||||
pytest = [
|
||||
{file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
|
||||
{file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
|
||||
]
|
||||
pytest-asyncio = [
|
||||
{file = "pytest-asyncio-0.17.1.tar.gz", hash = "sha256:f97d63cbe7b7a9eec30d1e289688201bd8e91cd1a854f6be4937b0bc4d2dff61"},
|
||||
{file = "pytest_asyncio-0.17.1-py3-none-any.whl", hash = "sha256:4b3f94b558a035edc5e14d66500ed9fbcc387ea7c3d561a0492006b9f938389e"},
|
||||
]
|
||||
pydantic = []
|
||||
pyflakes = []
|
||||
pyparsing = []
|
||||
pypika-tortoise = []
|
||||
pyproject-flake8 = []
|
||||
pytest = []
|
||||
pytest-asyncio = []
|
||||
pytest-forked = [
|
||||
{file = "pytest-forked-1.4.0.tar.gz", hash = "sha256:8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e"},
|
||||
{file = "pytest_forked-1.4.0-py3-none-any.whl", hash = "sha256:bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8"},
|
||||
]
|
||||
pytest-mock = [
|
||||
{file = "pytest-mock-3.6.1.tar.gz", hash = "sha256:40217a058c52a63f1042f0784f62009e976ba824c418cced42e88d5f40ab0e62"},
|
||||
{file = "pytest_mock-3.6.1-py3-none-any.whl", hash = "sha256:30c2f2cc9759e76eee674b81ea28c9f0b94f8f0445a1b87762cadf774f0df7e3"},
|
||||
]
|
||||
pytest-mock = []
|
||||
pytest-xdist = [
|
||||
{file = "pytest-xdist-2.5.0.tar.gz", hash = "sha256:4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf"},
|
||||
{file = "pytest_xdist-2.5.0-py3-none-any.whl", hash = "sha256:6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65"},
|
||||
]
|
||||
pytz = [
|
||||
{file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"},
|
||||
{file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"},
|
||||
]
|
||||
pyyaml = [
|
||||
{file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
|
||||
{file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
|
||||
{file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
|
||||
{file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
|
||||
{file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
|
||||
{file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
|
||||
{file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
|
||||
]
|
||||
pytz = []
|
||||
pyyaml = []
|
||||
smmap = [
|
||||
{file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"},
|
||||
{file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"},
|
||||
@@ -889,48 +788,34 @@ stevedore = [
|
||||
{file = "stevedore-3.5.0-py3-none-any.whl", hash = "sha256:a547de73308fd7e90075bb4d301405bebf705292fa90a90fc3bcf9133f58616c"},
|
||||
{file = "stevedore-3.5.0.tar.gz", hash = "sha256:f40253887d8712eaa2bb0ea3830374416736dc8ec0e22f5a65092c1174c44335"},
|
||||
]
|
||||
toml = [
|
||||
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
|
||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||
]
|
||||
tomli = [
|
||||
{file = "tomli-1.2.3-py3-none-any.whl", hash = "sha256:e3069e4be3ead9668e21cb9b074cd948f7b3113fd9c8bba083f48247aab8b11c"},
|
||||
{file = "tomli-1.2.3.tar.gz", hash = "sha256:05b6166bff487dc068d322585c7ea4ef78deed501cc124060e0f238e89a9231f"},
|
||||
]
|
||||
tomlkit = [
|
||||
{file = "tomlkit-0.8.0-py3-none-any.whl", hash = "sha256:b824e3466f1d475b2b5f1c392954c6cb7ea04d64354ff7300dc7c14257dc85db"},
|
||||
{file = "tomlkit-0.8.0.tar.gz", hash = "sha256:29e84a855712dfe0e88a48f6d05c21118dbafb283bb2eed614d46f80deb8e9a1"},
|
||||
]
|
||||
tortoise-orm = [
|
||||
{file = "tortoise-orm-0.18.1.tar.gz", hash = "sha256:537361ce2d0829741afd43afd9bc9413a314a176cb58747d88047c20ccc01db1"},
|
||||
{file = "tortoise_orm-0.18.1-py3-none-any.whl", hash = "sha256:edc9f3b49635b1dd74f73de38f54e031377e4f02b3698322502047f2e031af8b"},
|
||||
]
|
||||
tomli = []
|
||||
tomlkit = []
|
||||
tortoise-orm = []
|
||||
typed-ast = [
|
||||
{file = "typed_ast-1.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d8314c92414ce7481eee7ad42b353943679cf6f30237b5ecbf7d835519e1212"},
|
||||
{file = "typed_ast-1.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b53ae5de5500529c76225d18eeb060efbcec90ad5e030713fe8dab0fb4531631"},
|
||||
{file = "typed_ast-1.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:24058827d8f5d633f97223f5148a7d22628099a3d2efe06654ce872f46f07cdb"},
|
||||
{file = "typed_ast-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:a6d495c1ef572519a7bac9534dbf6d94c40e5b6a608ef41136133377bba4aa08"},
|
||||
{file = "typed_ast-1.5.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:de4ecae89c7d8b56169473e08f6bfd2df7f95015591f43126e4ea7865928677e"},
|
||||
{file = "typed_ast-1.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:256115a5bc7ea9e665c6314ed6671ee2c08ca380f9d5f130bd4d2c1f5848d695"},
|
||||
{file = "typed_ast-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:7c42707ab981b6cf4b73490c16e9d17fcd5227039720ca14abe415d39a173a30"},
|
||||
{file = "typed_ast-1.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:71dcda943a471d826ea930dd449ac7e76db7be778fcd722deb63642bab32ea3f"},
|
||||
{file = "typed_ast-1.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4f30a2bcd8e68adbb791ce1567fdb897357506f7ea6716f6bbdd3053ac4d9471"},
|
||||
{file = "typed_ast-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ca9e8300d8ba0b66d140820cf463438c8e7b4cdc6fd710c059bfcfb1531d03fb"},
|
||||
{file = "typed_ast-1.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9caaf2b440efb39ecbc45e2fabde809cbe56272719131a6318fd9bf08b58e2cb"},
|
||||
{file = "typed_ast-1.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c9bcad65d66d594bffab8575f39420fe0ee96f66e23c4d927ebb4e24354ec1af"},
|
||||
{file = "typed_ast-1.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:591bc04e507595887160ed7aa8d6785867fb86c5793911be79ccede61ae96f4d"},
|
||||
{file = "typed_ast-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:a80d84f535642420dd17e16ae25bb46c7f4c16ee231105e7f3eb43976a89670a"},
|
||||
{file = "typed_ast-1.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:38cf5c642fa808300bae1281460d4f9b7617cf864d4e383054a5ef336e344d32"},
|
||||
{file = "typed_ast-1.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b6ab14c56bc9c7e3c30228a0a0b54b915b1579613f6e463ba6f4eb1382e7fd4"},
|
||||
{file = "typed_ast-1.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2b8d7007f6280e36fa42652df47087ac7b0a7d7f09f9468f07792ba646aac2d"},
|
||||
{file = "typed_ast-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:b6d17f37f6edd879141e64a5db17b67488cfeffeedad8c5cec0392305e9bc775"},
|
||||
{file = "typed_ast-1.5.1.tar.gz", hash = "sha256:484137cab8ecf47e137260daa20bafbba5f4e3ec7fda1c1e69ab299b75fa81c5"},
|
||||
]
|
||||
typing-extensions = [
|
||||
{file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"},
|
||||
{file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"},
|
||||
]
|
||||
zipp = [
|
||||
{file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"},
|
||||
{file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"},
|
||||
{file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"},
|
||||
{file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"},
|
||||
{file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"},
|
||||
{file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"},
|
||||
{file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"},
|
||||
{file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"},
|
||||
]
|
||||
typing-extensions = []
|
||||
zipp = []
|
||||
|
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "aerich"
|
||||
version = "0.6.2"
|
||||
version = "0.7.1"
|
||||
description = "A database migrations tool for Tortoise ORM."
|
||||
authors = ["long2ice <long2ice@gmail.com>"]
|
||||
license = "Apache-2.0"
|
||||
@@ -20,7 +20,7 @@ tortoise-orm = "*"
|
||||
click = "*"
|
||||
asyncpg = { version = "*", optional = true }
|
||||
asyncmy = { version = "*", optional = true }
|
||||
ddlparse = "*"
|
||||
pydantic = "*"
|
||||
dictdiffer = "*"
|
||||
tomlkit = "*"
|
||||
|
||||
@@ -34,14 +34,34 @@ pytest-asyncio = "*"
|
||||
bandit = "*"
|
||||
pytest-mock = "*"
|
||||
cryptography = "*"
|
||||
pyproject-flake8 = "*"
|
||||
|
||||
[tool.poetry.extras]
|
||||
asyncmy = ["asyncmy"]
|
||||
asyncpg = ["asyncpg"]
|
||||
|
||||
[tool.aerich]
|
||||
tortoise_orm = "conftest.tortoise_orm"
|
||||
location = "./migrations"
|
||||
src_folder = "./."
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry>=0.12"]
|
||||
build-backend = "poetry.masonry.api"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
aerich = "aerich.cli:main"
|
||||
|
||||
[tool.black]
|
||||
line-length = 100
|
||||
target-version = ['py36', 'py37', 'py38', 'py39']
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_mode = 'auto'
|
||||
|
||||
[tool.mypy]
|
||||
pretty = true
|
||||
ignore_missing_imports = true
|
||||
|
||||
[tool.flake8]
|
||||
ignore = 'E501,W503,E203'
|
||||
|
@@ -29,6 +29,7 @@ class User(Model):
|
||||
is_active = fields.BooleanField(default=True, description="Is Active")
|
||||
is_superuser = fields.BooleanField(default=False, description="Is SuperUser")
|
||||
intro = fields.TextField(default="")
|
||||
longitude = fields.DecimalField(max_digits=10, decimal_places=8)
|
||||
|
||||
|
||||
class Email(Model):
|
||||
|
@@ -29,6 +29,7 @@ class User(Model):
|
||||
is_superuser = fields.BooleanField(default=False, description="Is SuperUser")
|
||||
avatar = fields.CharField(max_length=200, default="")
|
||||
intro = fields.TextField(default="")
|
||||
longitude = fields.DecimalField(max_digits=12, decimal_places=9)
|
||||
|
||||
|
||||
class Email(Model):
|
||||
|
@@ -72,18 +72,16 @@ def test_modify_column():
|
||||
ret1 = Migrate.ddl.modify_column(User, User._meta.fields_map.get("is_active").describe(False))
|
||||
if isinstance(Migrate.ddl, MysqlDDL):
|
||||
assert ret0 == "ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200)"
|
||||
assert (
|
||||
ret1
|
||||
== "ALTER TABLE `user` MODIFY COLUMN `is_active` BOOL NOT NULL COMMENT 'Is Active' DEFAULT 1"
|
||||
)
|
||||
elif isinstance(Migrate.ddl, PostgresDDL):
|
||||
assert (
|
||||
ret0
|
||||
== 'ALTER TABLE "category" ALTER COLUMN "name" TYPE VARCHAR(200) USING "name"::VARCHAR(200)'
|
||||
)
|
||||
|
||||
if isinstance(Migrate.ddl, MysqlDDL):
|
||||
assert (
|
||||
ret1
|
||||
== "ALTER TABLE `user` MODIFY COLUMN `is_active` BOOL NOT NULL COMMENT 'Is Active' DEFAULT 1"
|
||||
)
|
||||
elif isinstance(Migrate.ddl, PostgresDDL):
|
||||
assert (
|
||||
ret1 == 'ALTER TABLE "user" ALTER COLUMN "is_active" TYPE BOOL USING "is_active"::BOOL'
|
||||
)
|
||||
|
@@ -644,6 +644,21 @@ old_models_describe = {
|
||||
"constraints": {},
|
||||
"db_field_types": {"": "TEXT", "mysql": "LONGTEXT"},
|
||||
},
|
||||
{
|
||||
"name": "longitude",
|
||||
"unique": False,
|
||||
"default": None,
|
||||
"indexed": False,
|
||||
"nullable": False,
|
||||
"db_column": "longitude",
|
||||
"docstring": None,
|
||||
"generated": False,
|
||||
"field_type": "DecimalField",
|
||||
"constraints": {},
|
||||
"description": None,
|
||||
"python_type": "decimal.Decimal",
|
||||
"db_field_types": {"": "DECIMAL(12,9)", "sqlite": "VARCHAR(40)"},
|
||||
},
|
||||
],
|
||||
"fk_fields": [],
|
||||
"backward_fk_fields": [
|
||||
@@ -787,104 +802,148 @@ def test_migrate(mocker: MockerFixture):
|
||||
Migrate.diff_models(models_describe, old_models_describe, False)
|
||||
Migrate._merge_operators()
|
||||
if isinstance(Migrate.ddl, MysqlDDL):
|
||||
assert sorted(Migrate.upgrade_operators) == sorted(
|
||||
[
|
||||
"ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200)",
|
||||
"ALTER TABLE `category` MODIFY COLUMN `slug` VARCHAR(100) NOT NULL",
|
||||
"ALTER TABLE `config` ADD `user_id` INT NOT NULL COMMENT 'User'",
|
||||
"ALTER TABLE `config` ADD CONSTRAINT `fk_config_user_17daa970` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE",
|
||||
"ALTER TABLE `config` ALTER COLUMN `status` DROP DEFAULT",
|
||||
"ALTER TABLE `email` ADD `address` VARCHAR(200) NOT NULL",
|
||||
"ALTER TABLE `email` DROP COLUMN `user_id`",
|
||||
"ALTER TABLE `configs` RENAME TO `config`",
|
||||
"ALTER TABLE `product` RENAME COLUMN `image` TO `pic`",
|
||||
"ALTER TABLE `email` RENAME COLUMN `id` TO `email_id`",
|
||||
"ALTER TABLE `product` ADD INDEX `idx_product_name_869427` (`name`, `type_db_alias`)",
|
||||
"ALTER TABLE `email` ADD INDEX `idx_email_email_4a1a33` (`email`)",
|
||||
"ALTER TABLE `product` ADD UNIQUE INDEX `uid_product_name_869427` (`name`, `type_db_alias`)",
|
||||
"ALTER TABLE `product` ALTER COLUMN `view_num` SET DEFAULT 0",
|
||||
"ALTER TABLE `user` DROP COLUMN `avatar`",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(100) NOT NULL",
|
||||
"CREATE TABLE IF NOT EXISTS `newmodel` (\n `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,\n `name` VARCHAR(50) NOT NULL\n) CHARACTER SET utf8mb4;",
|
||||
"ALTER TABLE `user` ADD UNIQUE INDEX `uid_user_usernam_9987ab` (`username`)",
|
||||
"CREATE TABLE `email_user` (`email_id` INT NOT NULL REFERENCES `email` (`email_id`) ON DELETE CASCADE,`user_id` INT NOT NULL REFERENCES `user` (`id`) ON DELETE CASCADE) CHARACTER SET utf8mb4",
|
||||
]
|
||||
)
|
||||
expected_upgrade_operators = {
|
||||
"ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200)",
|
||||
"ALTER TABLE `category` MODIFY COLUMN `slug` VARCHAR(100) NOT NULL",
|
||||
"ALTER TABLE `config` ADD `user_id` INT NOT NULL COMMENT 'User'",
|
||||
"ALTER TABLE `config` ADD CONSTRAINT `fk_config_user_17daa970` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE",
|
||||
"ALTER TABLE `config` ALTER COLUMN `status` DROP DEFAULT",
|
||||
"ALTER TABLE `config` MODIFY COLUMN `value` JSON NOT NULL",
|
||||
"ALTER TABLE `email` ADD `address` VARCHAR(200) NOT NULL",
|
||||
"ALTER TABLE `email` DROP COLUMN `user_id`",
|
||||
"ALTER TABLE `configs` RENAME TO `config`",
|
||||
"ALTER TABLE `product` RENAME COLUMN `image` TO `pic`",
|
||||
"ALTER TABLE `email` RENAME COLUMN `id` TO `email_id`",
|
||||
"ALTER TABLE `product` ADD INDEX `idx_product_name_869427` (`name`, `type_db_alias`)",
|
||||
"ALTER TABLE `email` ADD INDEX `idx_email_email_4a1a33` (`email`)",
|
||||
"ALTER TABLE `product` ADD UNIQUE INDEX `uid_product_name_869427` (`name`, `type_db_alias`)",
|
||||
"ALTER TABLE `product` ALTER COLUMN `view_num` SET DEFAULT 0",
|
||||
"ALTER TABLE `product` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
||||
"ALTER TABLE `product` MODIFY COLUMN `is_reviewed` BOOL NOT NULL COMMENT 'Is Reviewed'",
|
||||
"ALTER TABLE `user` DROP COLUMN `avatar`",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(100) NOT NULL",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `intro` LONGTEXT NOT NULL",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `last_login` DATETIME(6) NOT NULL COMMENT 'Last Login'",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `is_active` BOOL NOT NULL COMMENT 'Is Active' DEFAULT 1",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `is_superuser` BOOL NOT NULL COMMENT 'Is SuperUser' DEFAULT 0",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `longitude` DECIMAL(10,8) NOT NULL",
|
||||
"ALTER TABLE `user` ADD UNIQUE INDEX `uid_user_usernam_9987ab` (`username`)",
|
||||
"CREATE TABLE `email_user` (\n `email_id` INT NOT NULL REFERENCES `email` (`email_id`) ON DELETE CASCADE,\n `user_id` INT NOT NULL REFERENCES `user` (`id`) ON DELETE CASCADE\n) CHARACTER SET utf8mb4",
|
||||
"CREATE TABLE IF NOT EXISTS `newmodel` (\n `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,\n `name` VARCHAR(50) NOT NULL\n) CHARACTER SET utf8mb4;",
|
||||
"ALTER TABLE `category` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
||||
"ALTER TABLE `product` MODIFY COLUMN `body` LONGTEXT NOT NULL",
|
||||
"ALTER TABLE `email` MODIFY COLUMN `is_primary` BOOL NOT NULL DEFAULT 0",
|
||||
}
|
||||
expected_downgrade_operators = {
|
||||
"ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200) NOT NULL",
|
||||
"ALTER TABLE `category` MODIFY COLUMN `slug` VARCHAR(200) NOT NULL",
|
||||
"ALTER TABLE `config` DROP COLUMN `user_id`",
|
||||
"ALTER TABLE `config` DROP FOREIGN KEY `fk_config_user_17daa970`",
|
||||
"ALTER TABLE `config` ALTER COLUMN `status` SET DEFAULT 1",
|
||||
"ALTER TABLE `email` ADD `user_id` INT NOT NULL",
|
||||
"ALTER TABLE `email` DROP COLUMN `address`",
|
||||
"ALTER TABLE `config` RENAME TO `configs`",
|
||||
"ALTER TABLE `product` RENAME COLUMN `pic` TO `image`",
|
||||
"ALTER TABLE `email` RENAME COLUMN `email_id` TO `id`",
|
||||
"ALTER TABLE `product` DROP INDEX `idx_product_name_869427`",
|
||||
"ALTER TABLE `email` DROP INDEX `idx_email_email_4a1a33`",
|
||||
"ALTER TABLE `product` DROP INDEX `uid_product_name_869427`",
|
||||
"ALTER TABLE `product` ALTER COLUMN `view_num` DROP DEFAULT",
|
||||
"ALTER TABLE `user` ADD `avatar` VARCHAR(200) NOT NULL DEFAULT ''",
|
||||
"ALTER TABLE `user` DROP INDEX `idx_user_usernam_9987ab`",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(200) NOT NULL",
|
||||
"DROP TABLE IF EXISTS `email_user`",
|
||||
"DROP TABLE IF EXISTS `newmodel`",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `intro` LONGTEXT NOT NULL",
|
||||
"ALTER TABLE `config` MODIFY COLUMN `value` TEXT NOT NULL",
|
||||
"ALTER TABLE `category` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
||||
"ALTER TABLE `product` MODIFY COLUMN `created_at` DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6)",
|
||||
"ALTER TABLE `product` MODIFY COLUMN `is_reviewed` BOOL NOT NULL COMMENT 'Is Reviewed'",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `last_login` DATETIME(6) NOT NULL COMMENT 'Last Login'",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `is_active` BOOL NOT NULL COMMENT 'Is Active' DEFAULT 1",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `is_superuser` BOOL NOT NULL COMMENT 'Is SuperUser' DEFAULT 0",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `longitude` DECIMAL(12,9) NOT NULL",
|
||||
"ALTER TABLE `product` MODIFY COLUMN `body` LONGTEXT NOT NULL",
|
||||
"ALTER TABLE `email` MODIFY COLUMN `is_primary` BOOL NOT NULL DEFAULT 0",
|
||||
}
|
||||
assert not set(Migrate.upgrade_operators).symmetric_difference(expected_upgrade_operators)
|
||||
|
||||
assert sorted(Migrate.downgrade_operators) == sorted(
|
||||
[
|
||||
"ALTER TABLE `category` MODIFY COLUMN `name` VARCHAR(200) NOT NULL",
|
||||
"ALTER TABLE `category` MODIFY COLUMN `slug` VARCHAR(200) NOT NULL",
|
||||
"ALTER TABLE `config` DROP COLUMN `user_id`",
|
||||
"ALTER TABLE `config` DROP FOREIGN KEY `fk_config_user_17daa970`",
|
||||
"ALTER TABLE `config` ALTER COLUMN `status` SET DEFAULT 1",
|
||||
"ALTER TABLE `email` ADD `user_id` INT NOT NULL",
|
||||
"ALTER TABLE `email` DROP COLUMN `address`",
|
||||
"ALTER TABLE `config` RENAME TO `configs`",
|
||||
"ALTER TABLE `product` RENAME COLUMN `pic` TO `image`",
|
||||
"ALTER TABLE `email` RENAME COLUMN `email_id` TO `id`",
|
||||
"ALTER TABLE `product` DROP INDEX `idx_product_name_869427`",
|
||||
"ALTER TABLE `email` DROP INDEX `idx_email_email_4a1a33`",
|
||||
"ALTER TABLE `product` DROP INDEX `uid_product_name_869427`",
|
||||
"ALTER TABLE `product` ALTER COLUMN `view_num` DROP DEFAULT",
|
||||
"ALTER TABLE `user` ADD `avatar` VARCHAR(200) NOT NULL DEFAULT ''",
|
||||
"ALTER TABLE `user` DROP INDEX `idx_user_usernam_9987ab`",
|
||||
"ALTER TABLE `user` MODIFY COLUMN `password` VARCHAR(200) NOT NULL",
|
||||
"DROP TABLE IF EXISTS `email_user`",
|
||||
"DROP TABLE IF EXISTS `newmodel`",
|
||||
]
|
||||
assert not set(Migrate.downgrade_operators).symmetric_difference(
|
||||
expected_downgrade_operators
|
||||
)
|
||||
|
||||
elif isinstance(Migrate.ddl, PostgresDDL):
|
||||
assert sorted(Migrate.upgrade_operators) == sorted(
|
||||
[
|
||||
'ALTER TABLE "category" ALTER COLUMN "name" DROP NOT NULL',
|
||||
'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(100) USING "slug"::VARCHAR(100)',
|
||||
'ALTER TABLE "config" ADD "user_id" INT NOT NULL',
|
||||
'ALTER TABLE "config" ADD CONSTRAINT "fk_config_user_17daa970" FOREIGN KEY ("user_id") REFERENCES "user" ("id") ON DELETE CASCADE',
|
||||
'ALTER TABLE "config" ALTER COLUMN "status" DROP DEFAULT',
|
||||
'ALTER TABLE "configs" RENAME TO "config"',
|
||||
'ALTER TABLE "email" ADD "address" VARCHAR(200) NOT NULL',
|
||||
'ALTER TABLE "email" DROP COLUMN "user_id"',
|
||||
'ALTER TABLE "email" RENAME COLUMN "id" TO "email_id"',
|
||||
'ALTER TABLE "product" ALTER COLUMN "view_num" SET DEFAULT 0',
|
||||
'ALTER TABLE "product" RENAME COLUMN "image" TO "pic"',
|
||||
'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(100) USING "password"::VARCHAR(100)',
|
||||
'ALTER TABLE "user" DROP COLUMN "avatar"',
|
||||
'CREATE INDEX "idx_product_name_869427" ON "product" ("name", "type_db_alias")',
|
||||
'CREATE INDEX "idx_email_email_4a1a33" ON "email" ("email")',
|
||||
'CREATE TABLE "email_user" ("email_id" INT NOT NULL REFERENCES "email" ("email_id") ON DELETE CASCADE,"user_id" INT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE)',
|
||||
'CREATE TABLE IF NOT EXISTS "newmodel" (\n "id" SERIAL NOT NULL PRIMARY KEY,\n "name" VARCHAR(50) NOT NULL\n);\nCOMMENT ON COLUMN "config"."user_id" IS \'User\';',
|
||||
'CREATE UNIQUE INDEX "uid_product_name_869427" ON "product" ("name", "type_db_alias")',
|
||||
'CREATE UNIQUE INDEX "uid_user_usernam_9987ab" ON "user" ("username")',
|
||||
]
|
||||
)
|
||||
assert sorted(Migrate.downgrade_operators) == sorted(
|
||||
[
|
||||
'ALTER TABLE "category" ALTER COLUMN "name" SET NOT NULL',
|
||||
'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(200) USING "slug"::VARCHAR(200)',
|
||||
'ALTER TABLE "config" ALTER COLUMN "status" SET DEFAULT 1',
|
||||
'ALTER TABLE "config" DROP COLUMN "user_id"',
|
||||
'ALTER TABLE "config" DROP CONSTRAINT "fk_config_user_17daa970"',
|
||||
'ALTER TABLE "config" RENAME TO "configs"',
|
||||
'ALTER TABLE "email" ADD "user_id" INT NOT NULL',
|
||||
'ALTER TABLE "email" DROP COLUMN "address"',
|
||||
'ALTER TABLE "email" RENAME COLUMN "email_id" TO "id"',
|
||||
'ALTER TABLE "product" ALTER COLUMN "view_num" DROP DEFAULT',
|
||||
'ALTER TABLE "product" RENAME COLUMN "pic" TO "image"',
|
||||
'ALTER TABLE "user" ADD "avatar" VARCHAR(200) NOT NULL DEFAULT \'\'',
|
||||
'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(200) USING "password"::VARCHAR(200)',
|
||||
'DROP INDEX "idx_product_name_869427"',
|
||||
'DROP INDEX "idx_email_email_4a1a33"',
|
||||
'DROP INDEX "idx_user_usernam_9987ab"',
|
||||
'DROP INDEX "uid_product_name_869427"',
|
||||
'DROP TABLE IF EXISTS "email_user"',
|
||||
'DROP TABLE IF EXISTS "newmodel"',
|
||||
]
|
||||
expected_upgrade_operators = {
|
||||
'ALTER TABLE "category" ALTER COLUMN "name" DROP NOT NULL',
|
||||
'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(100) USING "slug"::VARCHAR(100)',
|
||||
'ALTER TABLE "category" ALTER COLUMN "created_at" TYPE TIMESTAMPTZ USING "created_at"::TIMESTAMPTZ',
|
||||
'ALTER TABLE "config" ADD "user_id" INT NOT NULL',
|
||||
'ALTER TABLE "config" ADD CONSTRAINT "fk_config_user_17daa970" FOREIGN KEY ("user_id") REFERENCES "user" ("id") ON DELETE CASCADE',
|
||||
'ALTER TABLE "config" ALTER COLUMN "status" DROP DEFAULT',
|
||||
'ALTER TABLE "config" ALTER COLUMN "value" TYPE JSONB USING "value"::JSONB',
|
||||
'ALTER TABLE "configs" RENAME TO "config"',
|
||||
'ALTER TABLE "email" ADD "address" VARCHAR(200) NOT NULL',
|
||||
'ALTER TABLE "email" DROP COLUMN "user_id"',
|
||||
'ALTER TABLE "email" RENAME COLUMN "id" TO "email_id"',
|
||||
'ALTER TABLE "email" ALTER COLUMN "is_primary" TYPE BOOL USING "is_primary"::BOOL',
|
||||
'ALTER TABLE "product" ALTER COLUMN "view_num" SET DEFAULT 0',
|
||||
'ALTER TABLE "product" RENAME COLUMN "image" TO "pic"',
|
||||
'ALTER TABLE "product" ALTER COLUMN "is_reviewed" TYPE BOOL USING "is_reviewed"::BOOL',
|
||||
'ALTER TABLE "product" ALTER COLUMN "body" TYPE TEXT USING "body"::TEXT',
|
||||
'ALTER TABLE "product" ALTER COLUMN "created_at" TYPE TIMESTAMPTZ USING "created_at"::TIMESTAMPTZ',
|
||||
'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(100) USING "password"::VARCHAR(100)',
|
||||
'ALTER TABLE "user" DROP COLUMN "avatar"',
|
||||
'ALTER TABLE "user" ALTER COLUMN "is_superuser" TYPE BOOL USING "is_superuser"::BOOL',
|
||||
'ALTER TABLE "user" ALTER COLUMN "last_login" TYPE TIMESTAMPTZ USING "last_login"::TIMESTAMPTZ',
|
||||
'ALTER TABLE "user" ALTER COLUMN "intro" TYPE TEXT USING "intro"::TEXT',
|
||||
'ALTER TABLE "user" ALTER COLUMN "is_active" TYPE BOOL USING "is_active"::BOOL',
|
||||
'ALTER TABLE "user" ALTER COLUMN "longitude" TYPE DECIMAL(10,8) USING "longitude"::DECIMAL(10,8)',
|
||||
'CREATE INDEX "idx_product_name_869427" ON "product" ("name", "type_db_alias")',
|
||||
'CREATE INDEX "idx_email_email_4a1a33" ON "email" ("email")',
|
||||
'CREATE TABLE "email_user" (\n "email_id" INT NOT NULL REFERENCES "email" ("email_id") ON DELETE CASCADE,\n "user_id" INT NOT NULL REFERENCES "user" ("id") ON DELETE CASCADE\n)',
|
||||
'CREATE TABLE IF NOT EXISTS "newmodel" (\n "id" SERIAL NOT NULL PRIMARY KEY,\n "name" VARCHAR(50) NOT NULL\n);\nCOMMENT ON COLUMN "config"."user_id" IS \'User\';',
|
||||
'CREATE UNIQUE INDEX "uid_product_name_869427" ON "product" ("name", "type_db_alias")',
|
||||
'CREATE UNIQUE INDEX "uid_user_usernam_9987ab" ON "user" ("username")',
|
||||
}
|
||||
expected_downgrade_operators = {
|
||||
'ALTER TABLE "category" ALTER COLUMN "name" SET NOT NULL',
|
||||
'ALTER TABLE "category" ALTER COLUMN "slug" TYPE VARCHAR(200) USING "slug"::VARCHAR(200)',
|
||||
'ALTER TABLE "category" ALTER COLUMN "created_at" TYPE TIMESTAMPTZ USING "created_at"::TIMESTAMPTZ',
|
||||
'ALTER TABLE "config" ALTER COLUMN "status" SET DEFAULT 1',
|
||||
'ALTER TABLE "config" DROP COLUMN "user_id"',
|
||||
'ALTER TABLE "config" DROP CONSTRAINT "fk_config_user_17daa970"',
|
||||
'ALTER TABLE "config" RENAME TO "configs"',
|
||||
'ALTER TABLE "config" ALTER COLUMN "value" TYPE JSONB USING "value"::JSONB',
|
||||
'ALTER TABLE "email" ADD "user_id" INT NOT NULL',
|
||||
'ALTER TABLE "email" DROP COLUMN "address"',
|
||||
'ALTER TABLE "email" RENAME COLUMN "email_id" TO "id"',
|
||||
'ALTER TABLE "email" ALTER COLUMN "is_primary" TYPE BOOL USING "is_primary"::BOOL',
|
||||
'ALTER TABLE "product" ALTER COLUMN "view_num" DROP DEFAULT',
|
||||
'ALTER TABLE "product" RENAME COLUMN "pic" TO "image"',
|
||||
'ALTER TABLE "user" ADD "avatar" VARCHAR(200) NOT NULL DEFAULT \'\'',
|
||||
'ALTER TABLE "user" ALTER COLUMN "password" TYPE VARCHAR(200) USING "password"::VARCHAR(200)',
|
||||
'ALTER TABLE "user" ALTER COLUMN "last_login" TYPE TIMESTAMPTZ USING "last_login"::TIMESTAMPTZ',
|
||||
'ALTER TABLE "user" ALTER COLUMN "is_superuser" TYPE BOOL USING "is_superuser"::BOOL',
|
||||
'ALTER TABLE "user" ALTER COLUMN "is_active" TYPE BOOL USING "is_active"::BOOL',
|
||||
'ALTER TABLE "user" ALTER COLUMN "intro" TYPE TEXT USING "intro"::TEXT',
|
||||
'ALTER TABLE "user" ALTER COLUMN "longitude" TYPE DECIMAL(12,9) USING "longitude"::DECIMAL(12,9)',
|
||||
'ALTER TABLE "product" ALTER COLUMN "created_at" TYPE TIMESTAMPTZ USING "created_at"::TIMESTAMPTZ',
|
||||
'ALTER TABLE "product" ALTER COLUMN "is_reviewed" TYPE BOOL USING "is_reviewed"::BOOL',
|
||||
'ALTER TABLE "product" ALTER COLUMN "body" TYPE TEXT USING "body"::TEXT',
|
||||
'DROP INDEX "idx_product_name_869427"',
|
||||
'DROP INDEX "idx_email_email_4a1a33"',
|
||||
'DROP INDEX "idx_user_usernam_9987ab"',
|
||||
'DROP INDEX "uid_product_name_869427"',
|
||||
'DROP TABLE IF EXISTS "email_user"',
|
||||
'DROP TABLE IF EXISTS "newmodel"',
|
||||
}
|
||||
assert not set(Migrate.upgrade_operators).symmetric_difference(expected_upgrade_operators)
|
||||
assert not set(Migrate.downgrade_operators).symmetric_difference(
|
||||
expected_downgrade_operators
|
||||
)
|
||||
|
||||
elif isinstance(Migrate.ddl, SqliteDDL):
|
||||
assert Migrate.upgrade_operators == []
|
||||
|
||||
assert Migrate.downgrade_operators == []
|
||||
|
||||
|
||||
@@ -892,18 +951,18 @@ def test_sort_all_version_files(mocker):
|
||||
mocker.patch(
|
||||
"os.listdir",
|
||||
return_value=[
|
||||
"1_datetime_update.sql",
|
||||
"11_datetime_update.sql",
|
||||
"10_datetime_update.sql",
|
||||
"2_datetime_update.sql",
|
||||
"1_datetime_update.py",
|
||||
"11_datetime_update.py",
|
||||
"10_datetime_update.py",
|
||||
"2_datetime_update.py",
|
||||
],
|
||||
)
|
||||
|
||||
Migrate.migrate_location = "."
|
||||
|
||||
assert Migrate.get_all_version_files() == [
|
||||
"1_datetime_update.sql",
|
||||
"2_datetime_update.sql",
|
||||
"10_datetime_update.sql",
|
||||
"11_datetime_update.sql",
|
||||
"1_datetime_update.py",
|
||||
"2_datetime_update.py",
|
||||
"10_datetime_update.py",
|
||||
"11_datetime_update.py",
|
||||
]
|
||||
|
6
tests/test_utils.py
Normal file
6
tests/test_utils.py
Normal file
@@ -0,0 +1,6 @@
|
||||
from aerich.utils import import_py_file
|
||||
|
||||
|
||||
def test_import_py_file():
|
||||
m = import_py_file("aerich/utils.py")
|
||||
assert getattr(m, "import_py_file")
|
Reference in New Issue
Block a user