|
26 | 26 |
|
27 | 27 | """ |
28 | 28 |
|
29 | | -from configparser import ConfigParser |
30 | 29 | import logging |
31 | 30 | import os |
32 | 31 | import re |
33 | | -import subprocess |
34 | | -from tempfile import NamedTemporaryFile |
35 | 32 | from typing import Tuple |
36 | 33 |
|
37 | | -from alembic.config import Config as AlembicConfig |
38 | | -from alembic.util.exc import CommandError |
| 34 | +from alembic.command import revision as mk_revision |
| 35 | +from alembic.config import CommandLine, Config as AlembicConfig |
39 | 36 | from alembic.runtime.migration import MigrationContext |
40 | 37 | from alembic.runtime.environment import EnvironmentContext |
41 | 38 | from alembic.script import ScriptDirectory |
| 39 | +from alembic.util.exc import CommandError |
42 | 40 | from sqlalchemy.engine import create_engine |
43 | 41 |
|
44 | 42 | from cardinal_pythonlib.fileops import preserve_cwd |
45 | | -from cardinal_pythonlib.sqlalchemy.session import get_safe_url_from_url |
46 | 43 |
|
47 | 44 | log = logging.getLogger(__name__) |
48 | 45 |
|
@@ -377,55 +374,25 @@ def create_database_migration_numbered_style( |
377 | 374 | new_seq_str = str(new_seq_no).zfill(n_sequence_chars) |
378 | 375 |
|
379 | 376 | log.info( |
380 | | - f""" |
381 | | -Generating new revision with Alembic... |
382 | | - Last revision was: {current_seq_str} |
383 | | - New revision will be: {new_seq_str} |
384 | | - [If it fails with "Can't locate revision identified by...", you might need |
385 | | - to DROP the Alembic version table (by default named 'alembic_version', but |
386 | | - you may have elected to change that in your env.py).] |
387 | | -""" |
| 377 | + f"Generating new revision with Alembic. " |
| 378 | + f"Last revision was: {current_seq_str}. " |
| 379 | + f"New revision will be: {new_seq_str}. " |
| 380 | + f"(If the process fails with \"Can't locate revision identified " |
| 381 | + f'by...", you might need to DROP the Alembic version table; by ' |
| 382 | + f"default that is named {DEFAULT_ALEMBIC_VERSION_TABLE!r}, but you " |
| 383 | + f"may have elected to change that in your 'env.py' file.)" |
388 | 384 | ) |
389 | 385 |
|
390 | 386 | alembic_ini_dir = os.path.dirname(alembic_ini_file) |
| 387 | + os.chdir(alembic_ini_dir) |
391 | 388 |
|
392 | | - def _call_alembic(_alembic_ini_filename): |
393 | | - os.chdir(alembic_ini_dir) |
394 | | - cmdargs = [ |
395 | | - "alembic", |
396 | | - "-c", |
397 | | - _alembic_ini_filename, |
398 | | - "revision", |
399 | | - "--autogenerate", |
400 | | - "-m", |
401 | | - message, |
402 | | - "--rev-id", |
403 | | - new_seq_str, |
404 | | - ] |
405 | | - log.info(f"From directory {alembic_ini_dir!r}, calling: {cmdargs!r}") |
406 | | - subprocess.call(cmdargs) |
407 | | - |
| 389 | + # https://github.com/sqlalchemy/alembic/discussions/1089 |
| 390 | + namespace = CommandLine().parser.parse_args(["revision", "--autogenerate"]) |
| 391 | + config = AlembicConfig(alembic_ini_file, cmd_opts=namespace) |
408 | 392 | if db_url: |
409 | | - # Override the database URL. This is a bit ugly, because it's not |
410 | | - # obvious how to pass a URL directly to the "alembic revision" command. |
411 | | - # I don't think there's an API for that, and "alembic revision --help" |
412 | | - # doesn't show any URL options. So, a temporary config: |
413 | | - safe_url = get_safe_url_from_url(db_url) |
414 | | - alembic_cfg = AlembicConfig(alembic_ini_file) |
415 | | - alembic_cfg.set_main_option("sqlalchemy.url", db_url) |
416 | | - with NamedTemporaryFile( |
417 | | - mode="w+t", dir=alembic_ini_dir, suffix=".ini" |
418 | | - ) as tmpfile: |
419 | | - log.info( |
420 | | - f"Overriding database URL with {safe_url}, " |
421 | | - f"via temporary file {tmpfile.name}" |
422 | | - ) |
423 | | - cfgparser: ConfigParser = alembic_cfg.file_config |
424 | | - cfgparser.write(tmpfile) |
425 | | - tmpfile.flush() |
426 | | - _call_alembic(tmpfile.name) |
427 | | - else: |
428 | | - _call_alembic(alembic_ini_file) |
| 393 | + config.set_main_option("sqlalchemy.url", db_url) |
| 394 | + |
| 395 | + mk_revision(config, message=message, autogenerate=True, rev_id=new_seq_str) |
429 | 396 |
|
430 | 397 |
|
431 | 398 | def stamp_allowing_unusual_version_table( |
|
0 commit comments