TODO: store version in db

This commit is contained in:
long2ice 2020-05-21 18:38:45 +08:00
parent 23dd29644c
commit ea1191bb10
5 changed files with 33 additions and 17 deletions

View File

@ -40,8 +40,10 @@ parser = ConfigParser()
@click.pass_context @click.pass_context
async def cli(ctx: Context, config, app, name): async def cli(ctx: Context, config, app, name):
ctx.ensure_object(dict) ctx.ensure_object(dict)
ctx.obj["config"] = config ctx.obj["config_file"] = config
ctx.obj["name"] = name ctx.obj["name"] = name
ctx.obj["app"] = app
invoked_subcommand = ctx.invoked_subcommand invoked_subcommand = ctx.invoked_subcommand
if invoked_subcommand != "init": if invoked_subcommand != "init":
if not os.path.exists(config): if not os.path.exists(config):
@ -55,7 +57,6 @@ async def cli(ctx: Context, config, app, name):
ctx.obj["config"] = tortoise_config ctx.obj["config"] = tortoise_config
ctx.obj["location"] = location ctx.obj["location"] = location
ctx.obj["app"] = app
if invoked_subcommand != "init-db": if invoked_subcommand != "init-db":
try: try:
@ -72,7 +73,7 @@ async def migrate(ctx: Context, name):
location = ctx.obj["location"] location = ctx.obj["location"]
app = ctx.obj["app"] app = ctx.obj["app"]
ret = Migrate.migrate(name) ret = await Migrate.migrate(name)
if not ret: if not ret:
return click.secho("No changes detected", fg=Color.yellow) return click.secho("No changes detected", fg=Color.yellow)
Migrate.write_old_models(config, app, location) Migrate.write_old_models(config, app, location)
@ -156,21 +157,23 @@ def history(ctx):
async def init( async def init(
ctx: Context, tortoise_orm, location, ctx: Context, tortoise_orm, location,
): ):
config = ctx.obj["config"] config_file = ctx.obj["config_file"]
name = ctx.obj["name"] name = ctx.obj["name"]
if os.path.exists(config_file):
return click.secho("You have inited", fg=Color.yellow)
parser.add_section(name) parser.add_section(name)
parser.set(name, "tortoise_orm", tortoise_orm) parser.set(name, "tortoise_orm", tortoise_orm)
parser.set(name, "location", location) parser.set(name, "location", location)
with open(config, "w") as f: with open(config_file, "w") as f:
parser.write(f) parser.write(f)
if not os.path.isdir(location): if not os.path.isdir(location):
os.mkdir(location) os.mkdir(location)
click.secho(f"Success create migrate location {location}", fg=Color.green) click.secho(f"Success create migrate location {location}", fg=Color.green)
click.secho(f"Success generate config file {config}", fg=Color.green) click.secho(f"Success generate config file {config_file}", fg=Color.green)
@cli.command(help="Generate schema and generate app migrate location.") @cli.command(help="Generate schema and generate app migrate location.")
@ -191,8 +194,6 @@ async def init_db(ctx: Context, safe):
if not os.path.isdir(dirname): if not os.path.isdir(dirname):
os.mkdir(dirname) os.mkdir(dirname)
click.secho(f"Success create app migrate location {dirname}", fg=Color.green) click.secho(f"Success create app migrate location {dirname}", fg=Color.green)
else:
return click.secho(f'Already inited app "{app}"', fg=Color.yellow)
Migrate.write_old_models(config, app, location) Migrate.write_old_models(config, app, location)

View File

@ -17,6 +17,7 @@ from tortoise.fields import Field
from aerich.ddl import BaseDDL from aerich.ddl import BaseDDL
from aerich.exceptions import ConfigurationError from aerich.exceptions import ConfigurationError
from aerich.models import Aerich
from aerich.utils import get_app_connection from aerich.utils import get_app_connection
@ -88,27 +89,26 @@ class Migrate:
raise NotImplementedError("Current only support MySQL") raise NotImplementedError("Current only support MySQL")
@classmethod @classmethod
def _generate_diff_sql(cls, name): async def _generate_diff_sql(cls, name):
now = datetime.now().strftime("%Y%M%D%H%M%S").replace("/", "") now = datetime.now().strftime("%Y%M%D%H%M%S").replace("/", "")
filename = f"{cls._get_latest_version() + 1}_{now}_{name}.json" version = f"{cls._get_latest_version() + 1}_{now}_{name}"
filename = f"{version}.json"
content = { content = {
"upgrade": cls.upgrade_operators, "upgrade": cls.upgrade_operators,
"downgrade": cls.downgrade_operators, "downgrade": cls.downgrade_operators,
"migrate": False,
} }
with open(os.path.join(cls.migrate_location, filename), "w") as f: with open(os.path.join(cls.migrate_location, filename), "w") as f:
json.dump(content, f, indent=2, ensure_ascii=False) json.dump(content, f, indent=2, ensure_ascii=False)
await Aerich.create(version=version)
return filename return filename
@classmethod @classmethod
def migrate(cls, name): async def migrate(cls, name):
""" """
diff old models and new models to generate diff content diff old models and new models to generate diff content
:param name: :param name:
:return: :return:
""" """
if not cls.migrate_config:
raise ConfigurationError("You must call init_with_old_models() first!")
apps = Tortoise.apps apps = Tortoise.apps
diff_models = apps.get(cls.diff_app) diff_models = apps.get(cls.diff_app)
app_models = apps.get(cls.app) app_models = apps.get(cls.app)
@ -121,7 +121,7 @@ class Migrate:
if not cls.upgrade_operators: if not cls.upgrade_operators:
return False return False
return cls._generate_diff_sql(name) return await cls._generate_diff_sql(name)
@classmethod @classmethod
def _add_operator(cls, operator: str, upgrade=True, fk=False): def _add_operator(cls, operator: str, upgrade=True, fk=False):
@ -159,7 +159,8 @@ class Migrate:
with open(model_file, "r") as f: with open(model_file, "r") as f:
content = f.read() content = f.read()
ret = re.sub(pattern, rf"\2{cls.diff_app}\4\5", content) ret = re.sub(pattern, rf"\2{cls.diff_app}\4\5", content)
with open(old_model_file, "w" if i == 0 else "w+a") as f: mode = "w" if i == 0 else "a"
with open(old_model_file, mode) as f:
f.write(ret) f.write(ret)
@classmethod @classmethod

8
aerich/models.py Normal file
View File

@ -0,0 +1,8 @@
from tortoise import Model, fields
class Aerich(Model):
version = fields.CharField(max_length=50)
class Meta:
ordering = ["-id"]

View File

@ -6,6 +6,6 @@ from tortoise.contrib.test import finalizer, initializer
@pytest.fixture(scope="module", autouse=True) @pytest.fixture(scope="module", autouse=True)
def initialize_tests(request): def initialize_tests(request):
db_url = os.environ.get("TEST_DB", "sqlite://:memory:") db_url = os.getenv("TEST_DB", "sqlite://:memory:")
initializer(["tests.models"], db_url=db_url) initializer(["tests.models"], db_url=db_url)
request.addfinalizer(finalizer) request.addfinalizer(finalizer)

View File

@ -0,0 +1,6 @@
TORTOISE_ORM = {
"connections": {"default": "mysql://root:123456@127.0.0.1:3306/test"},
"apps": {
"models": {"models": ["tests.models", "aerich.models"], "default_connection": "default",},
},
}