İstediğiniz şey , Alembic belgelerinde en yaygın olan şema geçişinin aksine bir veri geçişidir.
Bu cevap, modellerinizi tanımlamak için bildirime dayalı (class-Mapper-Table veya core yerine) kullandığınızı varsayar. Bunu diğer biçimlere uyarlamak görece basit olmalıdır.
Alembic'in bazı temel veri işlevlerini sağladığını unutmayın: op.bulk_insert()
veop.execute()
. İşlemler oldukça azsa, bunları kullanın. Taşıma, ilişkiler veya diğer karmaşık etkileşimler gerektiriyorsa, aşağıda açıklandığı gibi modellerin ve oturumların tüm gücünü kullanmayı tercih ederim.
Aşağıda, bir oturumdaki verileri işlemek için kullanılacak bazı bildirimsel modelleri ayarlayan örnek bir geçiş betiği verilmiştir. Kilit noktalar şunlardır:
İhtiyacınız olan temel modelleri ihtiyaç duyacağınız sütunlarla tanımlayın. Her sütuna ihtiyacınız yok, sadece birincil anahtara ve kullanacağınızlara ihtiyacınız var.
Yükseltme işlevi içinde kullanın op.get_bind()
mevcut bağlantıyı almak ve onunla bir oturum yapmak için kullanın.
- Veya
bind.execute()
doğrudan SQL sorguları yazmak için SQLAlchemy'nin alt düzeyini kullanmak için kullanın. Bu, basit geçişler için kullanışlıdır.
Modelleri ve oturumu uygulamanızda normalde yaptığınız gibi kullanın.
"""create teams table
Revision ID: 169ad57156f0
Revises: 29b4c2bfce6d
Create Date: 2014-06-25 09:00:06.784170
"""
revision = '169ad57156f0'
down_revision = '29b4c2bfce6d'
from alembic import op
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Player(Base):
__tablename__ = 'players'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String, nullable=False)
team_name = sa.Column('team', sa.String, nullable=False)
team_id = sa.Column(sa.Integer, sa.ForeignKey('teams.id'), nullable=False)
team = orm.relationship('Team', backref='players')
class Team(Base):
__tablename__ = 'teams'
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String, nullable=False, unique=True)
def upgrade():
bind = op.get_bind()
session = orm.Session(bind=bind)
Team.__table__.create(bind)
op.add_column('players', sa.Column('team_id', sa.ForeignKey('teams.id'), nullable=False)
teams = {name: Team(name=name) for name in session.query(Player.team).distinct()}
session.add_all(teams.values())
for player in session.query(Player):
player.team = teams[player.team_name]
session.commit()
op.drop_column('players', 'team')
def downgrade():
bind = op.get_bind()
session = orm.Session(bind=bind)
op.add_column('players', sa.Column('team', sa.String, nullable=False)
for player in session.query(Player):
player.team_name = player.team.name
session.commit()
op.drop_column('players', 'team_id')
op.drop_table('teams')
Geçiş, ayrı modelleri tanımlar çünkü kodunuzdaki modeller veritabanının mevcut durumunu temsil ederken geçişler yoldaki adımları temsil eder . Veritabanınız bu yol boyunca herhangi bir durumda olabilir, bu nedenle modeller henüz veritabanıyla senkronize olmayabilir. Çok dikkatli olmadığınız sürece, gerçek modelleri doğrudan kullanmak eksik sütunlarda, geçersiz verilerde vb. Sorunlara neden olacaktır. Taşıma sırasında tam olarak hangi sütun ve modelleri kullanacağınızı açıkça belirtmek daha açıktır.
op.execute
içindeupgrade()
, tarafından kullanılmak üzere varsayılan bir şablon sağlamak için bir yol yokturalembic revision
komutu (üretilen için varsayılan bir vücuda.py
dosyası)?