2017-08-15 33 views
1

我有一個數據庫中的預先存在的表,我想使用automap patternSqlalchemy;將主鍵設置爲預先存在的數據庫表(不使用sqlite)

但是,要能夠使用此模式,您需要設置文檔中顯示的主鍵(並嘗試自己;失敗,如this)。

sqlalchemy有什麼方法可以將主鍵設置爲已有的id列嗎?(理想情況下從Users對象如下所示)。

順便說一句,我正在使用postgresql(vs sqlite其doesn't seem to allow setting a primary after a table has been created)。


FYI

到目前爲止,我已經能夠成功地訪問數據如下:

from sqlalchemy import Table, MetaData 
from sqlalchemy.orm import sessionmaker 

metadata = MetaData(engine) 
Users = Table('users', metadata, autoload=True) 

Session = sessionmaker(bind=engine) 
session = Session() 
user_q = session.query(Users).filter(Users.c.id==1) 

但是這給了我一個名單,我需要使用索引來訪問值。我希望通過屬性(列)名稱爲給定行設置值,如通常在sqlalchemy中完成的那樣(例如,通過user.first_name = "John"語法)。

回答

1

使用原始DDL語句。如果列id已經是獨一無二的:

con = sqlalchemy.create_engine(url, client_encoding='utf8') 
con.execute('alter table my_table add primary key(id)') 

如果id列不是唯一的,你必須放棄它並重新創建:

con.execute('alter table my_table drop id') 
con.execute('alter table my_table add id serial primary key') 

在Postgres裏,以這種方式將自動填充柱添加一列在後續行中連續編號。

1

你可以改變基礎表,以及這將是從長遠來看,做正確的事情,但如果users.id值唯一標識一行,you can manually instruct SQLAlchemy to treat it as a primary key通過explicitly partially specifying the class mapping

Base = automap_base() 

class Users(Base) 
    __tablename__ = 'users' 
    # Override id column, the type must match. Automap handles the rest. 
    id = Column(Integer, primary_key=True)  

# Continue with the automapping. Will fill in the rest. 
Base.prepare(engine, reflect=True) 
+0

當我希望不使用原始sql的解決方案;我不想在使用之前在某個地方定義類(我知道這不是長期建議的模式)。然而,這個答案很有用,因爲這個解決方案也可以用於sqlite。 – Bentley4

+1

如果你想避免遷移中的原始SQL,並且沒有看過,我建議[alembic](http://alembic.zzzcomputing.com/en/latest/)。 –

相關問題