我试图弄清楚如何使用Alembic获取我的数据库版本。我已经将数据库设置为使用alembic并成功执行了升级和降级。我现在想从我自己的python脚本中获取此版本。
我试图创建一个用于执行此操作的函数
def get_current_database_version():
path = os.path.join(os.path.dirname(__file__), os.path.pardir)
alembic_cfg = Config(os.path.join(path, 'alembic.ini'))
current_rev = command.current(alembic_cfg, head_only=True)
return current_rev
此函数返回NoSectionError: No section: 'formatters'
然后我去了我的alembic.ini文件,检查它是否有格式化区域。这是我的alembic.ini文件:
# A generic, single database configuration.
[alembic]
# path to migration scripts
script_location = alembic
pyramid_config_file = ../../development.ini
# template used to generate migration files
# file_template = %%(rev)s_%%(slug)s
# max length of characters to apply to the
# "slug" field
#truncate_slug_length = 40
# set to 'true' to run the environment during
# the 'revision' command, regardless of autogenerate
# revision_environment = false
# set to 'true' to allow .pyc and .pyo files without
# a source .py file to be detected as revisions in the
# versions/ directory
# sourceless = false
sqlalchemy.url = sqlite:///%(here)s/mgo.sqlite
# Logging configuration
[loggers]
keys = root,sqlalchemy,alembic
[handlers]
keys = console
[formatters]
keys = generic
[logger_root]
level = WARN
handlers = console
qualname =
[logger_sqlalchemy]
level = WARN
handlers =
qualname = sqlalchemy.engine
[logger_alembic]
level = INFO
handlers =
qualname = alembic
[handler_console]
class = StreamHandler
args = (sys.stderr,)
level = NOTSET
formatter = generic
[formatter_generic]
format = %(levelname)-5.5s [%(name)s] %(message)s
datefmt = %H:%M:%S
任何人都知道我做错了什么?感谢
编辑:
这是我尝试使用MigrationContext来解决问题:
def get_database_revision():
engine = create_engine("sqlite:///../mgo.db")
conn = engine.connect()
context = MigrationContext.configure(conn)
current_rev = context.get_current_revision()
return current_rev
它连接但没有返回。使用sqlite浏览器我可以看到数据库中的版本没有设置为none。
答案 0 :(得分:8)
您可以MigrationContext
使用get the current version:
from alembic.migration import MigrationContext
from sqlalchemy import create_engine
engine = create_engine("postgresql://mydatabase")
conn = engine.connect()
context = MigrationContext.configure(conn)
current_rev = context.get_current_revision()
在env.py
内,你可以使用:
from alembic import context
migration_context = context.get_context()
current_rev = context.get_current_revision()
最后,它基本上归结为连接到数据库并查看alembic_version
表。它包含迁移版本作为值以及数据库当前所在的值(根据alembic)。所以你可以按照你想要的方式编写代码,只要这样你最终会做什么。
答案 1 :(得分:2)
这个问题很古老,但是我有一个解决方案,我认为它比到目前为止给出的解决方案简单一些。
主要观察结果是,在调用command.current
时,Alembic不使用Python内置的print
函数,而是在config对象上使用print_stdout
方法。因此,要捕获输出,只需重载print_stdout
函数!这对我有用:
def get_current_database_version():
path = os.path.join(os.path.dirname(__file__), os.path.pardir)
alembic_cfg = Config(os.path.join(path, 'alembic.ini'))
captured_text = None
def print_stdout(text, *arg):
nonlocal captured_text
captured_text = text
alembic_cfg.print_stdout = print_stdout
command.current(alembic_cfg)
return captured_text
答案 2 :(得分:1)
只想投入2美分。
首先,可能是MigrationContext对您没有用,因为您没有连接到正确的数据库。从我看到的文档中,create_engine将为您创建一个db,如果它找不到您指定的文件。这可能发生了,因为在您的示例中,您使用的是相对路径,这很容易混淆。
其次,最让我痛苦的是
command.current(alembic_cfg, head_only=True)
实际上只有显示当前版本,对我来说似乎是在eclipse中将值打印到控制台。函数本身总是返回None,这有点烦人,这就是需要MigrationContext的原因。
此外,如果您要检查当前版本,因为您想要了解数据库的状态而不实际更新它,那么您将需要使用ScriptDirectory http://alembic.readthedocs.org/en/latest/api/script.html#alembic.script.ScriptDirectory 及其各种方法,以确定MigrationContext返回的版本是否是当前头部,或者它是否甚至有效。
答案 3 :(得分:1)
我建议使用stdout Config()对象参数(请参见here)来允许将sys.stdout重定向到StringIO缓冲区,如下所示:
output_buffer = io.StringIO()
alembic_cfg = alembic_Config('/path/to/alembic.ini', stdout=output_buffer)
alembic_command.current(alembic_cfg)
output = output_buffer.getvalue()
print(output)
答案 4 :(得分:1)
仅基于James Fennel's答案,在获取历史记录的情况下,它只会输出一行。如果您希望所有输出(作为列表),可以执行以下操作:
def get_current_database_history(input_cfg, start_rev=None):
captured_text = []
def print_stdout(text, *arg):
nonlocal captured_text
captured_text.append(text)
input_cfg.print_stdout = print_stdout
if start_rev:
command.history(input_cfg, rev_range="{}:".format(start_rev))
else:
command.history(input_cfg)
return captured_text
答案 5 :(得分:1)
from alembic.config import Config
from alembic import command
from alembic.script import ScriptDirectory
from alembic.runtime.environment import EnvironmentContext
class DBMigrations:
def __init__(self):
self.alembic_cfg = Config("./alembic.ini")
self.alembic_cfg.set_main_option('sqlalchemy.url', DATABASE_URL)
self.script = ScriptDirectory.from_config(self.alembic_cfg)
def get_db_version(self):
current_version = ""
def display_version(rev, context):
for rev in self.script.get_all_current(rev):
nonlocal current_version
current_version = rev.cmd_format(verbose=False)
return []
with EnvironmentContext(self.alembic_cfg, self.script, fn=display_version, dont_mutate=True):
self.script.run_env()
return current_version.split()[0]
答案 6 :(得分:0)
这是一个临时修复程序,它返回正确的版本号。
def get_database_revision():
s = select(['version_num'],from_obj='alembic_version')
result = DBSession.execute(s).fetchone()
return result['version_num']
如果没有找到版本号,则此函数返回None。
答案 7 :(得分:-1)
黑客!使用sh
,在正确的目录中,它就像:
>>> from sh import alembic
>>> alembic("current")
4cad21a83709 (head)