2016-12-01 57 views
1

背景INFOS:Python的SQLAlchemy的瓶插入新列到表 - Heroku的PostgreSQL的

我有一個由Heroku的託管在一個PostgreSQL數據庫的應用程序。

我已經在這個數據庫中的一些數據,現在我不得不在我的一個表中添加一個新的行。

通常我刪除舊的數據庫並重新創建它。但是,如果項目實時生效,我將不得不更新表格而不會丟失數據。

我可以創建一個DUMP並刪除舊的數據庫,並像往常一樣重新創建它。然後,我可以使用腳本並將所有現有數據上傳到新的數據庫中。但是這感覺不對。

我需要什麼:

在我目前的狀況有博客數據table=blog在數據庫上,我需要插入新列到我的table=zimmer所以blog心不是甚至影響。

class Zimmer(Base): 
    __tablename__ = 'zimmer' 
    id = Column(Integer, primary_key=True) 
    infofeld = Column(Text, nullable=False) 
    land = Column(Text, nullable=False) 
    bundesland = Column(Text, nullable=False) 
    stadt = Column(Text, nullable=False) 
    plz = Column(Text, nullable=False) 
    strasse = Column(Text, nullable=False) 
    hausnr = Column(Text, nullable=True) 
    eigener_link = Column(Text, nullable=True) 
    zimmer_lat = Column(Float, nullable=False) 
    zimmer_lng = Column(Float, nullable=False) 
    reingestellt_am = Column(Date, nullable=False) 

這是新的價值:eigener_link = Column(Text, nullable=True)

我目前正在嘗試在本地主機上,但到目前爲止,我只得到ProgrammingError因爲每次我嘗試加載其中zimmer顯示一個網站,它說沒有列eigener_link(這是合乎邏輯的)。

我的嘗試:

我tryed到try exceptProgrammingError在它發生的線,這給了我一個InternalError。在這裏我tryed更新zimmer表並添加新列eigener_link

try: 
    for page in paginator: 
     pages_list.append(page.number) 
except ProgrammingError: 
    update(Zimmer).values(eigener_link='Ihr Link') 
    db_session.commit() 

它給了我一個InternalError。我通過pgAdmin檢查了數據庫,並且沒有添加新的值。

try: 
     for page in paginator: 
      pages_list.append(page.number) 
    except ProgrammingError: 
     db_session.execute('ALTER TABLE zimmer ADD eigener_link TEXT') 
     db_session.commit() 

這給了我也InternalError交易已被取消。

回答

2

好吧我用alembic來解決這個問題,這很簡單,花了我10分鐘。

您通過PIP例如安裝:

pip install alembic 

然後按照教程。

基本上你用你的app和init alembic進入你的文件夾一次,所以它創建了所有必要的alembic文件。

alembic.ini你改變你的數據庫的路徑(你在本地進行更改,不需要推送某些內容到heroku)。

然後,您使用alembic revision創建一個腳本,將更改應用於您的數據庫。你必須用編輯器打開這個創建的腳本才能添加更改。(更多在教程中)。

而最後你運行alembic upgrade head就是這樣!

在我的情況下,這是在腳本進行必要的更改:

def upgrade(): 
    op.add_column('zimmer', sa.Column('eigener_link', sa.Text)) 


def downgrade(): 
    op.drop_column('zimmer', 'eigener_link')