आप जो पूछ रहे हैं वह डेटा माइग्रेशन है , जैसा कि एलेम्बिक डॉक्स में प्रचलित स्कीमा माइग्रेशन के विपरीत है ।
यह उत्तर मानता है कि आप अपने मॉडलों को परिभाषित करने के लिए घोषणात्मक (वर्ग-मैपर-टेबल या कोर के विपरीत) का उपयोग कर रहे हैं। इसे अन्य रूपों के अनुकूल बनाने के लिए अपेक्षाकृत सरल होना चाहिए।
नोट करें कि एलेम्बिक कुछ बुनियादी डेटा फ़ंक्शन प्रदान करता है: op.bulk_insert()
और op.execute()
। यदि ऑपरेशन काफी कम हैं, तो उन का उपयोग करें। यदि माइग्रेशन के लिए रिश्तों या अन्य जटिल इंटरैक्शन की आवश्यकता होती है, तो मैं नीचे वर्णित के रूप में मॉडल और सत्रों की पूरी शक्ति का उपयोग करना पसंद करता हूं।
निम्नलिखित एक उदाहरण माइग्रेशन स्क्रिप्ट है जो कुछ घोषणात्मक मॉडल सेट करती है जिनका उपयोग सत्र में डेटा में हेरफेर करने के लिए किया जाएगा। प्रमुख बिंदु हैं:
उन बुनियादी मॉडलों को परिभाषित करें जिनकी आपको आवश्यकता है, उन कॉलमों के साथ जिनकी आपको आवश्यकता होगी। आपको प्रत्येक कॉलम की आवश्यकता नहीं है, बस प्राथमिक कुंजी और आपके द्वारा उपयोग किए जा रहे हैं।
नवीनीकरण फ़ंक्शन के भीतर, op.get_bind()
वर्तमान कनेक्शन प्राप्त करने के लिए उपयोग करें, और इसके साथ एक सत्र बनाएं।
- या
bind.execute()
SQL क्वेरी को सीधे लिखने के लिए SQLAlchemy के निचले स्तर का उपयोग करने के लिए उपयोग करें। यह साधारण प्रवास के लिए उपयोगी है।
मॉडल और सत्र का उपयोग करें जैसा कि आप आमतौर पर अपने आवेदन में करते हैं।
"""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)
# create the teams table and the players.team_id column
Team.__table__.create(bind)
op.add_column('players', sa.Column('team_id', sa.ForeignKey('teams.id'), nullable=False)
# create teams for each team name
teams = {name: Team(name=name) for name in session.query(Player.team).distinct()}
session.add_all(teams.values())
# set player team based on team name
for player in session.query(Player):
player.team = teams[player.team_name]
session.commit()
# don't need team name now that team relationship is set
op.drop_column('players', 'team')
def downgrade():
bind = op.get_bind()
session = orm.Session(bind=bind)
# re-add the players.team column
op.add_column('players', sa.Column('team', sa.String, nullable=False)
# set players.team based on team relationship
for player in session.query(Player):
player.team_name = player.team.name
session.commit()
op.drop_column('players', 'team_id')
op.drop_table('teams')
माइग्रेशन अलग-अलग मॉडल को परिभाषित करता है क्योंकि आपके कोड के मॉडल डेटाबेस की वर्तमान स्थिति का प्रतिनिधित्व करते हैं, जबकि माइग्रेशन रास्ते में चरणों का प्रतिनिधित्व करते हैं । आपका डेटाबेस उस पथ के साथ किसी भी स्थिति में हो सकता है, इसलिए मॉडल डेटाबेस के साथ अभी तक सिंक नहीं कर सकते हैं। जब तक आप बहुत सावधान न हों, वास्तविक मॉडल का सीधे उपयोग करने से अनुपलब्ध स्तंभों, अमान्य डेटा, आदि के साथ समस्याएँ उत्पन्न होंगी, यह स्पष्ट रूप से स्पष्ट है कि माइग्रेशन में आपके द्वारा उपयोग किए जाने वाले कॉलम और मॉडल क्या हैं।
op.execute
थाupgrade()
, क्याalembic revision
कमांड द्वारा उपयोग किए जाने के लिए एक डिफ़ॉल्ट टेम्पलेट प्रदान करने का एक तरीका है (उत्पन्न.py
फ़ाइल के लिए एक डिफ़ॉल्ट निकाय )?