【问题标题】:Using SQLAlchemy with Oracle and Flask, to create sequences for Primary Keys将 SQLAlchemy 与 Oracle 和 Flask 一起使用,为主键创建序列
【发布时间】:2016-06-16 23:10:52
【问题描述】:

当我将 SQLAlchemy 与 Oracle 一起使用时,我还必须为主键添加序列,但迁移不会自行创建序列。如何获得要创建的序列?

我已经尝试多次调整代码以让 SQLAlchemy 为主键创建 oracle 序列,但到目前为止,我还无法获得由 SQLAlchemy 创建的 Oracle 序列。到目前为止,我有一个非常简单的用户/角色设置,并且存在表,但不存在序列。它运行时没有显示错误。

Model 类如下所示:

class Role(SurrogatePK, Model):
    """A role for a user."""

    __tablename__ = 'roles'
    id = db.Column(db.Integer, db.Sequence(__tablename__ + '_id_seq'), primary_key=True)
    name = Column(db.String(80), unique=True, nullable=False)
    user_id = reference_col('users', nullable=True)
    user = relationship('User', backref='roles')

    def __init__(self, name, **kwargs):
        """Create instance."""
        db.Model.__init__(self, name=name, **kwargs)

我正在使用 Flask 和 SQLAlchemy,并且在我运行之后;

$ python manage.py db init
Creating directory <lots removed here>...done

$ $ python manage.py db migrate
INFO  [alembic.runtime.migration] Context impl OracleImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'users'
INFO  [alembic.autogenerate.compare] Detected added table 'roles'

我没有发现任何错误,一切看起来都很好。然而,在我跑完之后;

$ python manage.py db upgrade
INFO  [alembic.runtime.migration] Context impl OracleImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 61ca5eb70d06, empty message

我第一次尝试创建记录,它失败并显示:

sqlalchemy.exc.DatabaseError DatabaseError: (cx_Oracle.DatabaseError) ORA-02289: 序列不存在

如果我手动创建序列,它工作正常。

【问题讨论】:

  • 您是否在使用自动生成的 alembic 迁移脚本?
  • alembic 不是一个完全自动化的解决方案。您必须手动调整创建的迁移文件,因为它无法自行解决。在这种情况下,您似乎必须手动添加代码来创建/删除序列。
  • 啊,谢谢你提供的信息。

标签: python oracle flask sqlalchemy flask-sqlalchemy


【解决方案1】:

感谢 univerio,我发现 alembic 不会为您处理序列的创建。因此,基于此,我四处搜索,并提出了这个解决方案:

def upgrade():
    ### commands auto generated by Alembic - please adjust! ###

    # not sure of the sequence for creating an object, so just called execute below.
    # op.execute(sa.schema.CreateSequence(sa.Sequence("users_id_seq")))

    op.execute("create sequence roles_id_seq start with 1 increment by 1 nocache nocycle")
    op.execute("create sequence users_id_seq start with 1 increment by 1 nocache nocycle")

以及降级:

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.execute(sa.schema.DropSequence(sa.Sequence("roles_id_seq")))
    op.execute(sa.schema.DropSequence(sa.Sequence("users_id_seq")))

如您所见,不知道使用 nocache 创建序列的语法是什么,所以我直接调用了 SQL。这行得通,并创建了所需的序列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-28
    • 2017-08-20
    • 2015-01-05
    • 2014-01-17
    • 2020-03-13
    • 2011-06-01
    • 2023-04-05
    • 2013-10-07
    相关资源
    最近更新 更多