【问题标题】:Sqlalchemy; setting a primary key to a pre-existing db table (not using sqlite)炼金术;将主键设置为预先存在的数据库表(不使用 sqlite)
【发布时间】:2018-01-23 23:33:57
【问题描述】:

我想在数据库中使用automap pattern 上的预先存在的表。

但是,为了能够使用此模式,您需要按照文档中所示设置主键(我自己尝试过;失败,如 this)。

sqlalchemy 中是否有任何方法可以将主键设置为已经存在的 id 列?(最好来自下面显示的 Users 对象)。

顺便说一句,我正在使用 postgresql(与 doesn't seem to allow setting a primary after a table has been created 的 sqlite 相比)。


仅供参考

到目前为止,我已经能够成功访问数据如下:

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" 语法)。

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案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 中以这种方式添加一列将自动在后续行中使用连续数字填充该列。

    【讨论】:

      【解决方案2】:

      您也可以更改基础表,从长远来看这是正确的做法,但如果 users.id 中的值唯一标识一行,you can manually instruct SQLAlchemy to treat it as a primary key by 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)
      

      【讨论】:

      • 虽然我希望有一个不使用原始 sql 的解决方案;我不想在使用之前在某个地方定义这样的类(我知道这不是长期建议的模式)。但是,此答案很有用,因为此解决方案也可能适用于 sqlite。
      • 如果你想在迁移中避免使用原始 SQL,并且之前没有看过,我推荐alembic
      猜你喜欢
      • 2017-02-24
      • 2021-12-11
      • 1970-01-01
      • 2021-02-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-17
      相关资源
      最近更新 更多