首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python + SQLAlchemy + Oracle + sequences =无法插入新行

Python + SQLAlchemy + Oracle + sequences =无法插入新行
EN

Stack Overflow用户
提问于 2019-01-25 10:36:52
回答 2查看 2.4K关注 0票数 1

--首先,一些背景和问题描述:

我必须使用Oracle,并且需要用DBAL (SQLAlchemy)来覆盖它。用于BDD/CI等的本地开发DB使用MySQL,因此需要DBAL。所有东西都是用Python开发的。

连接,读取操作不是一个问题,但我不能插入任何东西,因为更可能的两个问题:顺序和日期。为了澄清我的要求:

  • 序列:是字符串字段,是前缀。"ABC123“。在数据库中,只需将'ABC'||TEST_SEQUENCE.NEXTVAL设置为默认值就可以解决问题。在DB级别上工作。我不知道如何使它工作和使用字符串前缀。
  • 日期:因为MySQL对字符串(例如2019-01-01 12:02:03)很满意,所以甲骨文显然是喜怒无常的。但是,我使用了datetime对象,它生成了datetime.datetime(2013, 1, 1, 12, 2, 3)作为日期值的sql,这对于Oracle来说不是有效的SQL,除非SQLAlchemy在DB中执行它之前做了一些魔术。

底线是,我需要一个DBAL配置,它既适用于Oracle,也适用于使用字符串前缀序列的MySQL。

这里有一个示例代码:

代码语言:javascript
复制
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey, DateTime, Float, create_engine, Sequence
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

class Person(Base):
    __tablename__ = 'PERSONS'

    id_seq = Sequence('PERSONS_SEQ', metadata=Base.metadata)
    id = Column('ID', String(20), id_seq, primary_key=True)
    created_date = Column('CREATED_DATE', DateTime)

    def __init__(self, created_date):
        self.created_date

engine = create_engine("<some connection string trolololo>")
Session = sessionmaker(bind=engine)
session = Session()

created_at = datetime.strptime('2019-01-01 12:02:03', '%Y-%m-%d %H:%M:%S')
new_person = Person(
    created_date=created_at
)
session.add(new_account_payments)
session.flush()
session.commit()

错误/问题

最初的问题是导致此错误的顺序:

代码语言:javascript
复制
sqlalchemy.orm.exc.FlushError: Instance <Person at 0x7f1d7fb2de48> has a NULL identity key.  If this is an auto-generated value, check that the database table allows generation of new primary key values, and that the mapped Column object is configured to expect these generated values.  Ensure also that this flush() is not occurring at an inappropriate time, such as within a load() event.

我尝试过添加autoincrement="auto",但这给我带来了不同的错误,表明它只处理INT而不是字符串。

由于上述问题,我没有检查日期格式是否有效,但是一旦解决了这个问题,我将更新线程。

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2019-01-25 10:51:46

根据医生们

虽然以上是一个突出的惯用模式,但在大多数情况下,建议使用MetaData参数显式地将序列与Sequence.metadata关联起来。

因此,尝试添加元数据并使用orm定义(如docs所示)。

代码语言:javascript
复制
class Person(Base):
    __tablename__ = 'PERSONS'


    id_seq = Sequence('PERSONS_SEQ', metadata=Base.metadata)
    id = Column(String(20), id_seq, server_default=id_seq.next_value(), primary_key=True)

    created_date = Column('CREATED_DATE', DateTime)
票数 2
EN

Stack Overflow用户

发布于 2019-01-28 17:30:50

经过长时间的实验,上面的示例减去__init__函数,session.flush()开始工作。我一次做几件实验,可能会使问题复杂化。

我仍然不知道如何在Sequence上强制前缀。如果有,请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54363535

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档