now alice is basic worked
This commit is contained in:
parent
a79f5c1dc6
commit
a99a06e563
22
.github/workflows/pypi.yml
vendored
Normal file
22
.github/workflows/pypi.yml
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
name: pypi
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'alice/__init__.py'
|
||||
- '.github/workflows/pypi.yml'
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Build dists
|
||||
run: |
|
||||
python3 setup.py sdist
|
||||
- name: Pypi Publish
|
||||
uses: pypa/gh-action-pypi-publish@master
|
||||
with:
|
||||
user: __token__
|
||||
password: ${{ secrets.pypi_password }}
|
@ -0,0 +1,10 @@
|
||||
=========
|
||||
ChangeLog
|
||||
=========
|
||||
|
||||
|
||||
0.1
|
||||
===
|
||||
0.1.1
|
||||
-----
|
||||
- Now alice is basic worked.
|
35
Makefile
35
Makefile
@ -7,13 +7,44 @@ help:
|
||||
@echo
|
||||
@echo "usage: make <target>"
|
||||
@echo "Targets:"
|
||||
@echo " up Updates dev/test dependencies"
|
||||
@echo " deps Ensure dev/test dependencies are installed"
|
||||
@echo " check Checks that build is sane"
|
||||
@echo " lint Reports all linter violations"
|
||||
@echo " test Runs all tests"
|
||||
@echo " style Auto-formats the code"
|
||||
@echo " style Auto-formats the code"
|
||||
|
||||
deps:
|
||||
@which pip-sync > /dev/null || pip install -q pip-tools
|
||||
@pip install -r requirements-dev.txt
|
||||
|
||||
up:
|
||||
CUSTOM_COMPILE_COMMAND="make up" pip-compile -o requirements-dev.txt -U
|
||||
sed -i "s/^-e .*/-e ./" requirements.txt
|
||||
|
||||
style: deps
|
||||
isort -rc $(checkfiles)
|
||||
black $(black_opts) $(checkfiles)
|
||||
black $(black_opts) $(checkfiles)
|
||||
|
||||
check: deps
|
||||
ifneq ($(shell which black),)
|
||||
black --check $(black_opts) $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
|
||||
endif
|
||||
flake8 $(checkfiles)
|
||||
mypy $(checkfiles)
|
||||
pylint -d C,W,R $(checkfiles)
|
||||
bandit -r $(checkfiles)
|
||||
python setup.py check -mrs
|
||||
|
||||
lint: deps
|
||||
ifneq ($(shell which black),)
|
||||
black --check $(black_opts) $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false)
|
||||
endif
|
||||
flake8 $(checkfiles)
|
||||
mypy $(checkfiles)
|
||||
pylint $(checkfiles)
|
||||
bandit -r $(checkfiles)
|
||||
python setup.py check -mrs
|
||||
|
||||
test: deps
|
||||
$(py_warn) py.test
|
120
README.rst
120
README.rst
@ -0,0 +1,120 @@
|
||||
=====
|
||||
Alice
|
||||
=====
|
||||
|
||||
.. image:: https://img.shields.io/pypi/v/alice.svg?style=flat
|
||||
:target: https://pypi.python.org/pypi/alice
|
||||
.. image:: https://img.shields.io/github/license/long2ice/alice
|
||||
:target: https://github.com/long2ice/alice
|
||||
.. image:: https://github.com/long2ice/alice/workflows/pypi/badge.svg
|
||||
:target: https://github.com/long2ice/alice/actions?query=workflow:pypi
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Tortoise-ORM is the best asyncio ORM now, but it lacks a database migrations tool like alembic for SQLAlchemy, or Django ORM with it's own migrations tool.
|
||||
|
||||
This project aim to be a best migrations tool for Tortoise-ORM and which written by one of contributors of Tortoise-ORM.
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
Just install from pypi:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ pip install alice
|
||||
|
||||
Quick Start
|
||||
===========
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ alice -h
|
||||
|
||||
Usage: alice [OPTIONS] COMMAND [ARGS]...
|
||||
|
||||
Options:
|
||||
--config TEXT Tortoise-ORM config module, will auto read config dict variable
|
||||
from it. [default: settings]
|
||||
--tortoise-orm TEXT Tortoise-ORM config dict variable. [default:
|
||||
TORTOISE_ORM]
|
||||
--location TEXT Migrate store location. [default: ./migrations]
|
||||
--app TEXT Tortoise-ORM app name. [default: models]
|
||||
-h, --help Show this message and exit.
|
||||
|
||||
Commands:
|
||||
downgrade Downgrade to previous version.
|
||||
heads Show current available heads in migrate location.
|
||||
history List all migrate items.
|
||||
init Init migrate location and generate schema, you must exec first.
|
||||
migrate Generate migrate changes file.
|
||||
upgrade Upgrade to latest version.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Init schema and migrate location
|
||||
--------------------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ alice --config tests.backends.mysql init
|
||||
|
||||
Success create migrate location ./migrations/models
|
||||
Success init for app "models"
|
||||
|
||||
Update models and make migrate
|
||||
------------------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ alice --config tests.backends.mysql migrate --name drop_column
|
||||
|
||||
Success migrate 1_202029051520102929_drop_column.json
|
||||
|
||||
Format of migrate filename is {version}_{datetime}_{name|update}.json
|
||||
|
||||
Upgrade to latest version
|
||||
-------------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ alice --config tests.backends.mysql upgrade
|
||||
|
||||
Success upgrade 1_202029051520102929_drop_column.json
|
||||
|
||||
Now your db is migrated to latest.
|
||||
|
||||
Downgrade to previous version
|
||||
-----------------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ alice --config tests.backends.mysql downgrade
|
||||
|
||||
Success downgrade 1_202029051520102929_drop_column.json
|
||||
|
||||
Now your db rollback to previous version.
|
||||
|
||||
Show history
|
||||
------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ alice --config tests.backends.mysql history
|
||||
|
||||
1_202029051520102929_drop_column.json
|
||||
|
||||
Show heads to be migrated
|
||||
-------------------------
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ alice --config tests.backends.mysql heads
|
||||
|
||||
1_202029051520102929_drop_column.json
|
||||
|
||||
License
|
||||
=======
|
||||
This project is licensed under the `MIT <https://github.com/long2ice/alice/blob/master/LICENSE>`_ License.
|
@ -1 +1 @@
|
||||
__version__ = "0.1.0"
|
||||
__version__ = "0.1.1"
|
||||
|
14
alice/cli.py
14
alice/cli.py
@ -5,7 +5,7 @@ import sys
|
||||
from enum import Enum
|
||||
|
||||
import asyncclick as click
|
||||
from asyncclick import BadOptionUsage, BadParameter, Context, UsageError
|
||||
from asyncclick import BadOptionUsage, Context, UsageError
|
||||
from tortoise import Tortoise, generate_schema_for_client
|
||||
|
||||
from alice.migrate import Migrate
|
||||
@ -23,7 +23,7 @@ class Color(str, Enum):
|
||||
"--config",
|
||||
default="settings",
|
||||
show_default=True,
|
||||
help="Tortoise-ORM config module, will read config variable from it.",
|
||||
help="Tortoise-ORM config module, will auto read dict config variable from it.",
|
||||
)
|
||||
@click.option(
|
||||
"--tortoise-orm",
|
||||
@ -44,10 +44,14 @@ async def cli(ctx: Context, config, tortoise_orm, location, app):
|
||||
raise BadOptionUsage(ctx=ctx, message=f'No module named "{config}"', option_name="--config")
|
||||
config = getattr(config_module, tortoise_orm, None)
|
||||
if not config:
|
||||
raise BadOptionUsage(f'Can\'t get "{tortoise_orm}" from module "{config_module}"', ctx=ctx)
|
||||
raise BadOptionUsage(
|
||||
option_name="--config",
|
||||
message=f'Can\'t get "{tortoise_orm}" from module "{config_module}"',
|
||||
ctx=ctx,
|
||||
)
|
||||
|
||||
if app not in config.get("apps").keys():
|
||||
raise BadOptionUsage(f'No app found in "{config}"', ctx=ctx)
|
||||
raise BadOptionUsage(option_name="--config", message=f'No app found in "{config}"', ctx=ctx)
|
||||
|
||||
ctx.obj["config"] = config
|
||||
ctx.obj["location"] = location
|
||||
@ -142,7 +146,7 @@ def history(ctx):
|
||||
|
||||
|
||||
@cli.command(
|
||||
help="Init migrate location and generate schema, you must exec first before other cmd."
|
||||
help="Init migrate location and generate schema, you must exec first."
|
||||
)
|
||||
@click.option(
|
||||
"--safe",
|
||||
|
@ -2,10 +2,10 @@ from typing import List, Type
|
||||
|
||||
from tortoise import BaseDBAsyncClient, ForeignKeyFieldInstance, Model
|
||||
from tortoise.backends.base.schema_generator import BaseSchemaGenerator
|
||||
from tortoise.fields import Field, JSONField, TextField, UUIDField
|
||||
from tortoise.fields import Field
|
||||
|
||||
|
||||
class DDL:
|
||||
class BaseDDL:
|
||||
schema_generator_cls: Type[BaseSchemaGenerator] = BaseSchemaGenerator
|
||||
DIALECT = "sql"
|
||||
_DROP_TABLE_TEMPLATE = "DROP TABLE {table_name} IF EXISTS"
|
||||
@ -23,108 +23,25 @@ class DDL:
|
||||
self.schema_generator = self.schema_generator_cls(client)
|
||||
|
||||
def create_table(self, model: "Type[Model]"):
|
||||
return self.schema_generator._get_table_sql(model, True)["table_creation_string"]
|
||||
raise NotImplementedError
|
||||
|
||||
def drop_table(self, model: "Type[Model]"):
|
||||
return self._DROP_TABLE_TEMPLATE.format(table_name=model._meta.db_table)
|
||||
raise NotImplementedError
|
||||
|
||||
def add_column(self, model: "Type[Model]", field_object: Field):
|
||||
db_table = model._meta.db_table
|
||||
default = field_object.default
|
||||
db_column = field_object.model_field_name
|
||||
auto_now_add = getattr(field_object, "auto_now_add", False)
|
||||
auto_now = getattr(field_object, "auto_now", False)
|
||||
if default is not None or auto_now or auto_now_add:
|
||||
if callable(default) or isinstance(field_object, (UUIDField, TextField, JSONField)):
|
||||
default = ""
|
||||
else:
|
||||
default = field_object.to_db_value(default, model)
|
||||
try:
|
||||
default = self.schema_generator._column_default_generator(
|
||||
db_table,
|
||||
db_column,
|
||||
self.schema_generator._escape_default_value(default),
|
||||
auto_now_add,
|
||||
auto_now,
|
||||
)
|
||||
except NotImplementedError:
|
||||
default = ""
|
||||
else:
|
||||
default = ""
|
||||
return self._ADD_COLUMN_TEMPLATE.format(
|
||||
table_name=db_table,
|
||||
column=self.schema_generator._create_string(
|
||||
db_column=field_object.model_field_name,
|
||||
field_type=field_object.get_for_dialect(self.DIALECT, "SQL_TYPE"),
|
||||
nullable="NOT NULL" if not field_object.null else "",
|
||||
unique="UNIQUE" if field_object.unique else "",
|
||||
comment=self.schema_generator._column_comment_generator(
|
||||
table=db_table,
|
||||
column=field_object.model_field_name,
|
||||
comment=field_object.description,
|
||||
)
|
||||
if field_object.description
|
||||
else "",
|
||||
is_primary_key=field_object.pk,
|
||||
default=default,
|
||||
),
|
||||
)
|
||||
raise NotImplementedError
|
||||
|
||||
def drop_column(self, model: "Type[Model]", column_name: str):
|
||||
return self._DROP_COLUMN_TEMPLATE.format(
|
||||
table_name=model._meta.db_table, column_name=column_name
|
||||
)
|
||||
raise NotImplementedError
|
||||
|
||||
def add_index(self, model: "Type[Model]", field_names: List[str], unique=False):
|
||||
return self._ADD_INDEX_TEMPLATE.format(
|
||||
unique="UNIQUE" if unique else "",
|
||||
index_name=self.schema_generator._generate_index_name(
|
||||
"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]),
|
||||
)
|
||||
raise NotImplementedError
|
||||
|
||||
def drop_index(self, model: "Type[Model]", field_names: List[str], unique=False):
|
||||
return self._DROP_INDEX_TEMPLATE.format(
|
||||
index_name=self.schema_generator._generate_index_name(
|
||||
"idx" if not unique else "uid", model, field_names
|
||||
),
|
||||
table_name=model._meta.db_table,
|
||||
)
|
||||
raise NotImplementedError
|
||||
|
||||
def add_fk(self, model: "Type[Model]", field: ForeignKeyFieldInstance):
|
||||
db_table = model._meta.db_table
|
||||
to_field_name = field.to_field_instance.source_field
|
||||
if not to_field_name:
|
||||
to_field_name = field.to_field_instance.model_field_name
|
||||
|
||||
fk_name = self.schema_generator._generate_fk_name(
|
||||
from_table=db_table,
|
||||
from_field=field.source_field or field.model_field_name + "_id",
|
||||
to_table=field.related_model._meta.db_table,
|
||||
to_field=to_field_name,
|
||||
)
|
||||
return self._ADD_FK_TEMPLATE.format(
|
||||
table_name=db_table,
|
||||
fk_name=fk_name,
|
||||
db_column=field.source_field or field.model_field_name + "_id",
|
||||
table=field.related_model._meta.db_table,
|
||||
field=to_field_name,
|
||||
on_delete=field.on_delete,
|
||||
)
|
||||
raise NotImplementedError
|
||||
|
||||
def drop_fk(self, model: "Type[Model]", field: ForeignKeyFieldInstance):
|
||||
to_field_name = field.to_field_instance.source_field
|
||||
if not to_field_name:
|
||||
to_field_name = field.to_field_instance.model_field_name
|
||||
db_table = model._meta.db_table
|
||||
return self._DROP_FK_TEMPLATE.format(
|
||||
table_name=db_table,
|
||||
fk_name=self.schema_generator._generate_fk_name(
|
||||
from_table=db_table,
|
||||
from_field=field.source_field or field.model_field_name + "_id",
|
||||
to_table=field.related_model._meta.db_table,
|
||||
to_field=to_field_name,
|
||||
),
|
||||
)
|
||||
raise NotImplementedError
|
||||
|
@ -1,8 +1,120 @@
|
||||
from typing import List, Type
|
||||
|
||||
from tortoise import ForeignKeyFieldInstance, Model
|
||||
from tortoise.backends.mysql.schema_generator import MySQLSchemaGenerator
|
||||
from tortoise.fields import Field, JSONField, TextField, UUIDField
|
||||
|
||||
from alice.ddl import DDL
|
||||
from alice.ddl import BaseDDL
|
||||
|
||||
|
||||
class MysqlDDL(DDL):
|
||||
class MysqlDDL(BaseDDL):
|
||||
schema_generator_cls = MySQLSchemaGenerator
|
||||
DIALECT = MySQLSchemaGenerator.DIALECT
|
||||
|
||||
def create_table(self, model: "Type[Model]"):
|
||||
return self.schema_generator._get_table_sql(model, True)["table_creation_string"]
|
||||
|
||||
def drop_table(self, model: "Type[Model]"):
|
||||
return self._DROP_TABLE_TEMPLATE.format(table_name=model._meta.db_table)
|
||||
|
||||
def add_column(self, model: "Type[Model]", field_object: Field):
|
||||
db_table = model._meta.db_table
|
||||
default = field_object.default
|
||||
db_column = field_object.model_field_name
|
||||
auto_now_add = getattr(field_object, "auto_now_add", False)
|
||||
auto_now = getattr(field_object, "auto_now", False)
|
||||
if default is not None or auto_now_add:
|
||||
if callable(default) or isinstance(field_object, (UUIDField, TextField, JSONField)):
|
||||
default = ""
|
||||
else:
|
||||
default = field_object.to_db_value(default, model)
|
||||
try:
|
||||
default = self.schema_generator._column_default_generator(
|
||||
db_table,
|
||||
db_column,
|
||||
self.schema_generator._escape_default_value(default),
|
||||
auto_now_add,
|
||||
auto_now,
|
||||
)
|
||||
except NotImplementedError:
|
||||
default = ""
|
||||
else:
|
||||
default = ""
|
||||
return self._ADD_COLUMN_TEMPLATE.format(
|
||||
table_name=db_table,
|
||||
column=self.schema_generator._create_string(
|
||||
db_column=field_object.model_field_name,
|
||||
field_type=field_object.get_for_dialect(self.DIALECT, "SQL_TYPE"),
|
||||
nullable="NOT NULL" if not field_object.null else "",
|
||||
unique="UNIQUE" if field_object.unique else "",
|
||||
comment=self.schema_generator._column_comment_generator(
|
||||
table=db_table,
|
||||
column=field_object.model_field_name,
|
||||
comment=field_object.description,
|
||||
)
|
||||
if field_object.description
|
||||
else "",
|
||||
is_primary_key=field_object.pk,
|
||||
default=default,
|
||||
),
|
||||
)
|
||||
|
||||
def drop_column(self, model: "Type[Model]", column_name: str):
|
||||
return self._DROP_COLUMN_TEMPLATE.format(
|
||||
table_name=model._meta.db_table, column_name=column_name
|
||||
)
|
||||
|
||||
def add_index(self, model: "Type[Model]", field_names: List[str], unique=False):
|
||||
return self._ADD_INDEX_TEMPLATE.format(
|
||||
unique="UNIQUE" if unique else "",
|
||||
index_name=self.schema_generator._generate_index_name(
|
||||
"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]),
|
||||
)
|
||||
|
||||
def drop_index(self, model: "Type[Model]", field_names: List[str], unique=False):
|
||||
return self._DROP_INDEX_TEMPLATE.format(
|
||||
index_name=self.schema_generator._generate_index_name(
|
||||
"idx" if not unique else "uid", model, field_names
|
||||
),
|
||||
table_name=model._meta.db_table,
|
||||
)
|
||||
|
||||
def add_fk(self, model: "Type[Model]", field: ForeignKeyFieldInstance):
|
||||
db_table = model._meta.db_table
|
||||
to_field_name = field.to_field_instance.source_field
|
||||
if not to_field_name:
|
||||
to_field_name = field.to_field_instance.model_field_name
|
||||
|
||||
db_column = field.source_field or field.model_field_name + "_id"
|
||||
fk_name = self.schema_generator._generate_fk_name(
|
||||
from_table=db_table,
|
||||
from_field=db_column,
|
||||
to_table=field.related_model._meta.db_table,
|
||||
to_field=to_field_name,
|
||||
)
|
||||
return self._ADD_FK_TEMPLATE.format(
|
||||
table_name=db_table,
|
||||
fk_name=fk_name,
|
||||
db_column=db_column,
|
||||
table=field.related_model._meta.db_table,
|
||||
field=to_field_name,
|
||||
on_delete=field.on_delete,
|
||||
)
|
||||
|
||||
def drop_fk(self, model: "Type[Model]", field: ForeignKeyFieldInstance):
|
||||
to_field_name = field.to_field_instance.source_field
|
||||
if not to_field_name:
|
||||
to_field_name = field.to_field_instance.model_field_name
|
||||
db_table = model._meta.db_table
|
||||
return self._DROP_FK_TEMPLATE.format(
|
||||
table_name=db_table,
|
||||
fk_name=self.schema_generator._generate_fk_name(
|
||||
from_table=db_table,
|
||||
from_field=field.source_field or field.model_field_name + "_id",
|
||||
to_table=field.related_model._meta.db_table,
|
||||
to_field=to_field_name,
|
||||
),
|
||||
)
|
||||
|
@ -9,7 +9,7 @@ from tortoise import BackwardFKRelation, ForeignKeyFieldInstance, Model, Tortois
|
||||
from tortoise.backends.mysql.schema_generator import MySQLSchemaGenerator
|
||||
from tortoise.fields import Field
|
||||
|
||||
from alice.ddl import DDL
|
||||
from alice.ddl import BaseDDL
|
||||
from alice.ddl.mysql import MysqlDDL
|
||||
from alice.exceptions import ConfigurationError
|
||||
from alice.utils import get_app_connection
|
||||
@ -21,7 +21,7 @@ class Migrate:
|
||||
_upgrade_fk_operators: List[str] = []
|
||||
_downgrade_fk_operators: List[str] = []
|
||||
|
||||
ddl: DDL
|
||||
ddl: BaseDDL
|
||||
migrate_config: dict
|
||||
old_models = "old_models"
|
||||
diff_app = "diff_models"
|
||||
@ -85,6 +85,11 @@ class Migrate:
|
||||
|
||||
@classmethod
|
||||
def migrate(cls, name):
|
||||
"""
|
||||
diff old models and new models to generate diff content
|
||||
:param name:
|
||||
:return:
|
||||
"""
|
||||
if not cls.migrate_config:
|
||||
raise ConfigurationError("You must call init_with_old_models() first!")
|
||||
apps = Tortoise.apps
|
||||
@ -103,6 +108,13 @@ class Migrate:
|
||||
|
||||
@classmethod
|
||||
def _add_operator(cls, operator: str, upgrade=True, fk=False):
|
||||
"""
|
||||
add operator,differentiate fk because fk is order limit
|
||||
:param operator:
|
||||
:param upgrade:
|
||||
:param fk:
|
||||
:return:
|
||||
"""
|
||||
if upgrade:
|
||||
if fk:
|
||||
cls._upgrade_fk_operators.append(operator)
|
||||
@ -134,6 +146,13 @@ class Migrate:
|
||||
|
||||
@classmethod
|
||||
def _get_migrate_config(cls, config: dict, app: str, location: str):
|
||||
"""
|
||||
generate tmp config with old models
|
||||
:param config:
|
||||
:param app:
|
||||
:param location:
|
||||
:return:
|
||||
"""
|
||||
temp_config = deepcopy(config)
|
||||
path = os.path.join(location, app, cls.old_models)
|
||||
path = path.replace("/", ".").lstrip(".")
|
||||
@ -142,6 +161,13 @@ class Migrate:
|
||||
|
||||
@classmethod
|
||||
def write_old_models(cls, config: dict, app: str, location: str):
|
||||
"""
|
||||
write new models to old models
|
||||
:param config:
|
||||
:param app:
|
||||
:param location:
|
||||
:return:
|
||||
"""
|
||||
old_model_files = []
|
||||
models = config.get("apps").get(app).get("models")
|
||||
for model in models:
|
||||
@ -235,6 +261,11 @@ class Migrate:
|
||||
|
||||
@classmethod
|
||||
def _exclude_field(cls, field: Field):
|
||||
"""
|
||||
exclude BackwardFKRelation
|
||||
:param field:
|
||||
:return:
|
||||
"""
|
||||
return isinstance(field, BackwardFKRelation)
|
||||
|
||||
@classmethod
|
||||
@ -251,11 +282,23 @@ class Migrate:
|
||||
return cls.ddl.drop_column(model, field.model_field_name)
|
||||
|
||||
@classmethod
|
||||
def _add_fk(cls, model: Type[Model], field: Field):
|
||||
def _add_fk(cls, model: Type[Model], field: ForeignKeyFieldInstance):
|
||||
"""
|
||||
add fk
|
||||
:param model:
|
||||
:param field:
|
||||
:return:
|
||||
"""
|
||||
return cls.ddl.add_fk(model, field)
|
||||
|
||||
@classmethod
|
||||
def _remove_fk(cls, model: Type[Model], field: Field):
|
||||
def _remove_fk(cls, model: Type[Model], field: ForeignKeyFieldInstance):
|
||||
"""
|
||||
drop fk
|
||||
:param model:
|
||||
:param field:
|
||||
:return:
|
||||
"""
|
||||
return cls.ddl.drop_fk(model, field)
|
||||
|
||||
@classmethod
|
||||
|
44
poetry.lock
generated
44
poetry.lock
generated
@ -259,7 +259,7 @@ description = "Alternative regular expression module, to replace re."
|
||||
name = "regex"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
version = "2020.5.13"
|
||||
version = "2020.5.14"
|
||||
|
||||
[[package]]
|
||||
category = "main"
|
||||
@ -470,27 +470,27 @@ pypika = [
|
||||
{file = "PyPika-0.37.6.tar.gz", hash = "sha256:64510fa36667e8bb654bdc1be5a3a77bac1dbc2f03d4848efac08e39d9cac6f5"},
|
||||
]
|
||||
regex = [
|
||||
{file = "regex-2020.5.13-cp27-cp27m-win32.whl", hash = "sha256:d20ba8d3a844d6cd9bbe127a60cc8f61cfe2d2b77da997775639999a48fbbfe3"},
|
||||
{file = "regex-2020.5.13-cp27-cp27m-win_amd64.whl", hash = "sha256:2cdf6bb8112a6b49092a9320edc823d41b21a06c8c7ac88a845b73462193f3ac"},
|
||||
{file = "regex-2020.5.13-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:9d801d3693c5a6af5a506f9905b0e6d8ae419a00054d8d80ed9d65f81fc37e1f"},
|
||||
{file = "regex-2020.5.13-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:705e334ac42cf807f33d4daafe58da33e23a93389233ab2f80f63dee09488d9b"},
|
||||
{file = "regex-2020.5.13-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:78014742b047ea2c9849e85db2dc84cad365b7f2dee404f86882d1fb9ff38df2"},
|
||||
{file = "regex-2020.5.13-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:078024a52a72c98f157c380bea7beab7e0b907854ca337e3d4eecd44b363d4fb"},
|
||||
{file = "regex-2020.5.13-cp36-cp36m-win32.whl", hash = "sha256:4088da3b99f1341c2904679ffbfe6f08f5cc13e5cad1c6b053728da7cf68d28c"},
|
||||
{file = "regex-2020.5.13-cp36-cp36m-win_amd64.whl", hash = "sha256:14026bf953137a5cdc6a2a8fda314a0296ce5cd6da6e46fe79d6e03caf3c1bac"},
|
||||
{file = "regex-2020.5.13-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:03284826c5f5cd4b252ab7d510cb4d6b7e7f849cdea8e1b384c57e0996a9a3f9"},
|
||||
{file = "regex-2020.5.13-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:36e6e7ca33a70f859e532110c2b1af28f98622424681e2e158f0f49735f1a9c8"},
|
||||
{file = "regex-2020.5.13-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:707d2fcfdce12ca946830839c4c243c1b258c0d2c61350dc2efe0af00a4d2fdf"},
|
||||
{file = "regex-2020.5.13-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:76668d1f91af08275313799bbd6ab04971ab08919defde886f5c94c7fc0f4623"},
|
||||
{file = "regex-2020.5.13-cp37-cp37m-win32.whl", hash = "sha256:0be1cb724d43a7fb017e868d809640de03be7db88ab83d212fd802bc3d0277a0"},
|
||||
{file = "regex-2020.5.13-cp37-cp37m-win_amd64.whl", hash = "sha256:9d42213927eede46bd4eb0c225600d82cf2b3c8882eb449f00b7cfa9bbf0975e"},
|
||||
{file = "regex-2020.5.13-cp38-cp38-manylinux1_i686.whl", hash = "sha256:7163cac9621e9099dc8768ddec32372f50893c934be961f58826d46f0668ea0c"},
|
||||
{file = "regex-2020.5.13-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:efae79f5eb3a6e2d9fa246605870887e0187ed66a4c56fc4cf22da00aa2ec220"},
|
||||
{file = "regex-2020.5.13-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:89d4a97682170c32a13c4223e72cf75f9d0c6223b40fb4abe717bbb6c271c6ea"},
|
||||
{file = "regex-2020.5.13-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4f144eb977800d7ef593893204c2e7f1f109e8a943f6e822990d22385b12c5d6"},
|
||||
{file = "regex-2020.5.13-cp38-cp38-win32.whl", hash = "sha256:3b7f9c0051179325d7efd76271b783de593a50608e48e130c1590a95ea411f59"},
|
||||
{file = "regex-2020.5.13-cp38-cp38-win_amd64.whl", hash = "sha256:3cec763e0428beb8668edf004aa9a8a4c1b502d0ecb97dc4d77e5a67a9077186"},
|
||||
{file = "regex-2020.5.13.tar.gz", hash = "sha256:cd931f9cca663617ba7a74b6500c6857405271b142edff68b2530e458b80a116"},
|
||||
{file = "regex-2020.5.14-cp27-cp27m-win32.whl", hash = "sha256:e565569fc28e3ba3e475ec344d87ed3cd8ba2d575335359749298a0899fe122e"},
|
||||
{file = "regex-2020.5.14-cp27-cp27m-win_amd64.whl", hash = "sha256:d466967ac8e45244b9dfe302bbe5e3337f8dc4dec8d7d10f5e950d83b140d33a"},
|
||||
{file = "regex-2020.5.14-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:27ff7325b297fb6e5ebb70d10437592433601c423f5acf86e5bc1ee2919b9561"},
|
||||
{file = "regex-2020.5.14-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:ea55b80eb0d1c3f1d8d784264a6764f931e172480a2f1868f2536444c5f01e01"},
|
||||
{file = "regex-2020.5.14-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:c9bce6e006fbe771a02bda468ec40ffccbf954803b470a0345ad39c603402577"},
|
||||
{file = "regex-2020.5.14-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:d881c2e657c51d89f02ae4c21d9adbef76b8325fe4d5cf0e9ad62f850f3a98fd"},
|
||||
{file = "regex-2020.5.14-cp36-cp36m-win32.whl", hash = "sha256:99568f00f7bf820c620f01721485cad230f3fb28f57d8fbf4a7967ec2e446994"},
|
||||
{file = "regex-2020.5.14-cp36-cp36m-win_amd64.whl", hash = "sha256:70c14743320a68c5dac7fc5a0f685be63bc2024b062fe2aaccc4acc3d01b14a1"},
|
||||
{file = "regex-2020.5.14-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:a7c37f048ec3920783abab99f8f4036561a174f1314302ccfa4e9ad31cb00eb4"},
|
||||
{file = "regex-2020.5.14-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:89d76ce33d3266173f5be80bd4efcbd5196cafc34100fdab814f9b228dee0fa4"},
|
||||
{file = "regex-2020.5.14-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:51f17abbe973c7673a61863516bdc9c0ef467407a940f39501e786a07406699c"},
|
||||
{file = "regex-2020.5.14-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:ce5cc53aa9fbbf6712e92c7cf268274eaff30f6bd12a0754e8133d85a8fb0f5f"},
|
||||
{file = "regex-2020.5.14-cp37-cp37m-win32.whl", hash = "sha256:8044d1c085d49673aadb3d7dc20ef5cb5b030c7a4fa253a593dda2eab3059929"},
|
||||
{file = "regex-2020.5.14-cp37-cp37m-win_amd64.whl", hash = "sha256:c2062c7d470751b648f1cacc3f54460aebfc261285f14bc6da49c6943bd48bdd"},
|
||||
{file = "regex-2020.5.14-cp38-cp38-manylinux1_i686.whl", hash = "sha256:329ba35d711e3428db6b45a53b1b13a0a8ba07cbbcf10bbed291a7da45f106c3"},
|
||||
{file = "regex-2020.5.14-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:579ea215c81d18da550b62ff97ee187b99f1b135fd894a13451e00986a080cad"},
|
||||
{file = "regex-2020.5.14-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:3a9394197664e35566242686d84dfd264c07b20f93514e2e09d3c2b3ffdf78fe"},
|
||||
{file = "regex-2020.5.14-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ce367d21f33e23a84fb83a641b3834dd7dd8e9318ad8ff677fbfae5915a239f7"},
|
||||
{file = "regex-2020.5.14-cp38-cp38-win32.whl", hash = "sha256:1386e75c9d1574f6aa2e4eb5355374c8e55f9aac97e224a8a5a6abded0f9c927"},
|
||||
{file = "regex-2020.5.14-cp38-cp38-win_amd64.whl", hash = "sha256:7e61be8a2900897803c293247ef87366d5df86bf701083b6c43119c7c6c99108"},
|
||||
{file = "regex-2020.5.14.tar.gz", hash = "sha256:ce450ffbfec93821ab1fea94779a8440e10cf63819be6e176eb1973a6017aff5"},
|
||||
]
|
||||
six = [
|
||||
{file = "six-1.14.0-py2.py3-none-any.whl", hash = "sha256:8f3cd2e254d8f793e7f3d6d9df77b92252b52637291d0f0da013c76ea2724b6c"},
|
||||
|
@ -1,31 +1,19 @@
|
||||
aiomysql==0.0.20
|
||||
aiosqlite==0.13.0
|
||||
anyio==1.3.0
|
||||
appdirs==1.4.4
|
||||
async-generator==1.10
|
||||
asyncclick==7.0.9
|
||||
asynctest==0.13.0
|
||||
attrs==19.3.0
|
||||
black==19.10b0
|
||||
cffi==1.14.0
|
||||
ciso8601==2.1.3; sys_platform != "win32" and implementation_name == "cpython"
|
||||
click==7.1.2
|
||||
cryptography==2.9.2
|
||||
flake8==3.8.1
|
||||
iso8601==0.1.12; sys_platform == "win32" or implementation_name != "cpython"
|
||||
isort==4.3.21
|
||||
mccabe==0.6.1
|
||||
pathspec==0.8.0
|
||||
pycodestyle==2.6.0
|
||||
pycparser==2.20
|
||||
pyflakes==2.2.0
|
||||
pymysql==0.9.2
|
||||
pypika==0.37.6
|
||||
regex==2020.5.13
|
||||
six==1.14.0
|
||||
sniffio==1.1.0
|
||||
taskipy==1.2.1
|
||||
toml==0.10.1
|
||||
-e git+https://github.com/tortoise/tortoise-orm.git@95c384a4742ee5980f8e4ae934bfdb0d8137bb40#egg=tortoise-orm
|
||||
typed-ast==1.4.1
|
||||
typing-extensions==3.7.4.2
|
||||
#
|
||||
# This file is autogenerated by pip-compile
|
||||
# To update, run:
|
||||
#
|
||||
# make up
|
||||
#
|
||||
aiomysql==0.0.20 # via alice (setup.py)
|
||||
aiosqlite==0.13.0 # via alice (setup.py)
|
||||
anyio==1.3.0 # via alice (setup.py), asyncclick
|
||||
async-generator==1.10 # via alice (setup.py), anyio
|
||||
asyncclick==7.0.9 # via alice (setup.py)
|
||||
cffi==1.14.0 # via alice (setup.py), cryptography
|
||||
cryptography==2.9.2 # via alice (setup.py), pymysql
|
||||
pycparser==2.20 # via alice (setup.py), cffi
|
||||
pymysql==0.9.2 # via aiomysql, alice (setup.py)
|
||||
pypika==0.37.6 # via alice (setup.py)
|
||||
six==1.14.0 # via alice (setup.py), cryptography
|
||||
sniffio==1.1.0 # via alice (setup.py), anyio
|
||||
typing-extensions==3.7.4.2 # via alice (setup.py)
|
||||
|
18
setup.cfg
Normal file
18
setup.cfg
Normal file
@ -0,0 +1,18 @@
|
||||
[flake8]
|
||||
max-line-length = 100
|
||||
exclude =
|
||||
ignore = E501,W503,DAR101,DAR201,DAR402
|
||||
|
||||
[darglint]
|
||||
docstring_style=sphinx
|
||||
|
||||
[isort]
|
||||
not_skip=__init__.py
|
||||
multi_line_output=3
|
||||
include_trailing_comma=True
|
||||
force_grid_wrap=0
|
||||
use_parentheses=True
|
||||
line_length=100
|
||||
|
||||
|
||||
|
3
setup.py
3
setup.py
@ -37,7 +37,8 @@ setup(
|
||||
},
|
||||
platforms='any',
|
||||
keywords=(
|
||||
'migrations Tortoise-ORM mysql'
|
||||
'migrate Tortoise-ORM mysql'
|
||||
),
|
||||
dependency_links=['https://github.com/tortoise/tortoise-orm.git@branch#egg=tortoise-orm'],
|
||||
install_requires=requirements(),
|
||||
)
|
||||
|
@ -29,8 +29,6 @@ class User(Model):
|
||||
is_superuser = fields.BooleanField(default=False, description="Is SuperUser")
|
||||
avatar = fields.CharField(max_length=200, default="")
|
||||
intro = fields.TextField(default="")
|
||||
created_at = fields.DatetimeField(auto_now_add=True)
|
||||
updated_at = fields.DatetimeField(auto_now=True)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.pk}#{self.username}"
|
||||
|
Loading…
x
Reference in New Issue
Block a user