client
テーブルにoauth secret
とoauth key
があります。次に、移行中に作成されるoauth credentials
テーブルにそれらを移動します。 Alembicは、アップグレード用に次のスキーマを作成しました。
from myapp.models import Client, ClientCredential
from alembic import op
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('client_credential',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.Column('client_id', sa.Integer(), nullable=False),
sa.Column('key', sa.String(length=22), nullable=False),
sa.Column('secret', sa.String(length=44), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['client_id'], ['client.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('key')
)
# Here I need to copy data from table A to newly created Table.
# Now Client table will not have secret and key attributes
clients = [{'secret': client.secret, 'key': client.key, 'is_active':True, 'client_id': client.id, 'created_at': sa.func.now(), 'updated_at': sa.func.now()} for client in Client.query.all()]
op.bulk_insert(ClientCredential, clients)
#Also replaced above two lines with
#connection = op.get_bind()
#print connection.execute(Client, Client.query.all())
op.drop_column(u'client', u'secret')
op.drop_column(u'client', u'key')
スクリプトがclients
またはconnection.execute
に入ると、アランビックスクリプトがハングします。 sqlalchemy logs
を有効にすると、Base.Engine
は空になります。 op.execute
も試してみましたが、運が悪かったです。
Log
INFO [alembic.migration] Context impl PostgresqlImpl.
INFO [alembic.migration] Will assume transactional DDL.
INFO [alembic.migration] Running upgrade 25e7a9839cd4 -> 176fb70348b9, Added ClientCredential
2013-09-10 23:59:08,144 INFO sqlalchemy.engine.base.Engine select version()
INFO [sqlalchemy.engine.base.Engine] select version()
2013-09-10 23:59:08,145 INFO sqlalchemy.engine.base.Engine {}
INFO [sqlalchemy.engine.base.Engine] {}
2013-09-10 23:59:08,146 INFO sqlalchemy.engine.base.Engine select current_schema()
INFO [sqlalchemy.engine.base.Engine] select current_schema()
2013-09-10 23:59:08,146 INFO sqlalchemy.engine.base.Engine {}
INFO [sqlalchemy.engine.base.Engine] {}
2013-09-10 23:59:08,148 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
INFO [sqlalchemy.engine.base.Engine] BEGIN (implicit)
2013-09-10 23:59:08,150 INFO sqlalchemy.engine.base.Engine SELECT client.id AS client_id, client.created_at AS client_created_at, client.updated_at AS client_updated_at, client.user_id AS client_user_id, client.org_id AS client_org_id, client.title AS client_title, client.description AS client_description, client.website AS client_website, client.redirect_uri AS client_redirect_uri, client.notification_uri AS client_notification_uri, client.iframe_uri AS client_iframe_uri, client.resource_uri AS client_resource_uri, client.active AS client_active, client.allow_any_login AS client_allow_any_login, client.team_access AS client_team_access, client.trusted AS client_trusted
FROM client
INFO [sqlalchemy.engine.base.Engine] SELECT client.id AS client_id, client.created_at AS client_created_at, client.updated_at AS client_updated_at, client.user_id AS client_user_id, client.org_id AS client_org_id, client.title AS client_title, client.description AS client_description, client.website AS client_website, client.redirect_uri AS client_redirect_uri, client.notification_uri AS client_notification_uri, client.iframe_uri AS client_iframe_uri, client.resource_uri AS client_resource_uri, client.active AS client_active, client.allow_any_login AS client_allow_any_login, client.team_access AS client_team_access, client.trusted AS client_trusted
FROM client
2013-09-10 23:59:08,150 INFO sqlalchemy.engine.base.Engine {}
INFO [sqlalchemy.engine.base.Engine] {}
アランビック移行を使用して、値をclient
テーブルからclient_credential
テーブルにコピーするにはどうすればよいですか?
ついに私は問題を解決しました。値をフェッチするための生のSQLを作成し、bulk_insert
を使用しました。
def upgrade():
### commands auto generated by Alembic - please adjust! ###
op.create_table('client_credential',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.Column('client_id', sa.Integer(), nullable=False),
sa.Column('key', sa.String(length=22), nullable=False),
sa.Column('secret', sa.String(length=44), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['client_id'], ['client.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('key')
)
#http://stackoverflow.com/questions/15725859/sqlalchemy-alembic-bulk-insert-fails-str-object-has-no-attribute-autoincre
client_credential = sa.sql.table('client_credential',
sa.Column('client_id', sa.Integer, nullable=False),
sa.Column('is_active', sa.Boolean, nullable=False, default=True),
sa.Column('key', sa.String(22), nullable=False, default=True),
sa.Column('secret', sa.String(22), nullable=False, default=True),
sa.Column('created_at', sa.DateTime, nullable=False, default=sa.func.now()),
sa.Column('updated_at', sa.DateTime, nullable=False, default=sa.func.now()),
)
conn = op.get_bind()
res = conn.execute("select secret, key, id from client")
results = res.fetchall()
clients = [{'secret': r[0], 'key': r[1], 'is_active':True, 'client_id': r[2], 'created_at': datetime.datetime.now(), 'updated_at': datetime.datetime.now()} for r in results]
op.bulk_insert(client_credential, clients)
op.drop_column(u'client', u'secret')
op.drop_column(u'client', u'key')
### end Alembic commands ###
Sqlalchemyエンジンバインドを使用してDBSessionを作成すると、SQLクエリの使用を回避できます。
from myapp.models import Client, ClientCredential
from alembic import op, context
import sqlalchemy as sa
def upgrade():
### commands auto generated by Alembic - please adjust! ###
url = context.config.get_main_option("sqlalchemy.url")
engine = sa.create_engine(url)
DBSession.configure(bind=engine)
op.create_table(
'client_credential',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False),
sa.Column('updated_at', sa.DateTime(), nullable=False),
sa.Column('client_id', sa.Integer(), nullable=False),
sa.Column('key', sa.String(length=22), nullable=False),
sa.Column('secret', sa.String(length=44), nullable=False),
sa.Column('is_active', sa.Boolean(), nullable=False),
sa.ForeignKeyConstraint(['client_id'], ['client.id'], ),
sa.PrimaryKeyConstraint('id'),
sa.UniqueConstraint('key'))
# Here I need to copy data from table A to newly created Table.
# Now Client table will not have secret and key attributes
clients = [
{'secret': client.secret,
'key': client.key,
'is_active': True,
'client_id': client.id,
'created_at': sa.func.now(),
'updated_at': sa.func.now()}
for client in Client.query.all()]
op.bulk_insert(ClientCredential, clients)
#Also replaced above two lines with
#connection = op.get_bind()
#print connection.execute(Client, Client.query.all())
op.drop_column(u'client', u'secret')
op.drop_column(u'client', u'key')