简体   繁体   English

当我希望通过升级中的Session对象更改数据时,如何测试alembic迁移?

[英]How do I test an alembic migration when I wish to alter the data via Session objects inside the upgrade?

I am trying to get alembic to do a database migration for me. 我想让alembic为我做一个数据库迁移。 I have made changes to my model which add two new columns, which will have data that is calculated based on the current rows in the table. 我对我的模型进行了更改,添加了两个新列,这些列将具有基于表中当前行计算的数据。 What I really want to do is figure out how to test what the migration is going to do before it actually does it. 我真正想要做的是弄清楚如何在实际迁移之前测试迁移的内容。 My understanding is the --sql argument would allow me to do that. 我的理解是--sql参数允许我这样做。

When I try to do the upgrade with --sql to test the migration before actually doing it, using the following command line: 当我尝试使用--sql进行升级以在实际执行之前测试迁移时,使用以下命令行:

alembic -c dev_alembic.ini upgrade --sql 3e0

I am receiving an error from alembic: 我收到了来自alembic的错误:

BEGIN TRANSACTION;

CREATE TABLE alembic_version (
    version_num VARCHAR(32) NOT NULL
);

GO

-- Running upgrade  -> 3e076afb70e1

ALTER TABLE sipendpoint ADD extension VARCHAR(50) NULL;

GO

ALTER TABLE sipendpoint ADD home_site VARCHAR(5) NULL;

GO

Traceback (most recent call last):
  File "/home/pgrace/venv/pyramid27/bin/alembic", line 9, in <module>
    load_entry_point('alembic==0.7.6', 'console_scripts', 'alembic')()
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/config.py", line 439, in main
    CommandLine(prog=prog).main(argv=argv)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/config.py", line 433, in main
    self.run_cmd(cfg, options)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/config.py", line 416, in run_cmd
    **dict((k, getattr(options, k)) for k in kwarg)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/command.py", line 165, in upgrade
    script.run_env()
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/script.py", line 390, in run_env
    util.load_python_file(self.dir, 'env.py')
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/util.py", line 243, in load_python_file
    module = load_module_py(module_id, path)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/compat.py", line 79, in load_module_py
    mod = imp.load_source(module_id, path, fp)
  File "alembic/env.py", line 65, in <module>
    run_migrations_offline()
  File "alembic/env.py", line 44, in run_migrations_offline
    context.run_migrations()
  File "<string>", line 7, in run_migrations
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/environment.py", line 738, in run_migrations
    self.get_context().run_migrations(**kw)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/alembic/migration.py", line 309, in run_migrations
    step.migration_fn(**kw)
  File "/home/pgrace/repo/stackcallrouterserver/alembic/versions/3e076afb70e1_add_extension_field_and_home_site_to_.py", line 48, in upgrade
    for entry in DBSession.query(SIPEndpoint):
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2515, in __iter__
    return self._execute_and_instances(context)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2528, in _execute_and_instances
    close_with_result=True)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2519, in _connection_from_session
    **kw)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 882, in connection
    execution_options=execution_options)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 887, in _connection_for_bind
    engine, execution_options)
  File "/home/pgrace/venv/pyramid27/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 344, in _connection_for_bind
    transaction = conn.begin()
AttributeError: 'MockConnection' object has no attribute 'begin'

Here is the migration file in question: 这是有问题的迁移文件:

# revision identifiers, used by Alembic.
revision = '3e076afb70e1'
down_revision = None
branch_labels = None
depends_on = None

from alembic import op
import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
import re
from scrserver.models import SIPEndpoint

from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    )

DBSession = scoped_session(sessionmaker(bind=op.get_bind()))
Base = declarative_base()
Base.metadata.bind = op.get_bind()

def sitecheck(x):
    try:
        return {
                '1.2.3.4': "FOO",
                '5.6.7.8': "BAR",
                '9.10.11.12': "BAZ"
                }
    except KeyError:
        return None

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.add_column('sipendpoint', sa.Column('extension', sa.String(length=50), nullable=True))
    op.add_column('sipendpoint', sa.Column('home_site', sa.String(length=5), nullable=True))

    ### end Alembic commands ###


    for entry in DBSession.query(SIPEndpoint):
        update=sa.update(SIPEndpoint).where(SIPEndpoint.addr==entry.addr).values(extension=entry.addr)
        op.execute(update)


def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('sipendpoint', 'home_site')
    op.drop_column('sipendpoint', 'extension')
    ### end Alembic commands ###

you cannot run this: 你不能运行这个:

for entry in DBSession.query(SIPEndpoint):

in --sql mode, because that is a SELECT statement. 在--sql模式下,因为这是一个SELECT语句。 There is no database with which to SELECT from in --sql mode. 在--sql模式下没有可用于SELECT的数据库。

There is no way to do a "dry run" of a script that wishes to have a conversation with the database, eg a script that relies on retrieving data from the database. 没有办法对希望与数据库进行对话的脚本进行“干运行”,例如依赖于数据库中检索数据的脚本。 --sql mode is limited to just those commands that require no interaction at all, eg CREATE, DROP and ALTER statements, and to an extremely limited degree, INSERT, UPDATE and DELETE statements, which must be emitted in very special ways such that they don't attempt to request information about the operation. --sql模式仅限于那些根本不需要交互的命令,例如CREATE,DROP和ALTER语句,以及极其有限的 INSERT,UPDATE和DELETE语句,它们必须以非常特殊的方式发出,以便它们不要尝试请求有关操作的信息。 For INSERT, the bulk insert style is recommended as it is designed to be compatible with --sql mode. 对于INSERT,建议使用批量插入样式,因为它与--sql模式兼容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM