Sqlalchemy没有主键(key) 向表中添加数据

Sqlalchemy没有主键(key) 向表中添加数据

sqlalchemy 如果写入操作是必须要有主键才可以操作的,我讲一下如果表中没有主键怎么绕过,保存数据。

一、重写sqlalchemy常用方法

# Engine
engine_oarcle = create_engine("oracle+cx_oracle://{}:{}@{}/{}".format(
    'user',
    'pass',
    '127.0.0.1',
    'orcl'), coerce_to_unicode=True, max_overflow=100, pool_size=100, pool_recycle=3600)

#自己写的一个数据类
class Connect(object):

    def __init__(self, engine):
        self.engine = engine
        self.session = None
        self.connect_session()

    def connect_session(self):
        try:
            self.engine.connect()
        except Exception:
            raise Exception("数据库连接失败")

        dbSession = orm.sessionmaker(bind=self.engine)
        self.session = dbSession()

    # 我重写了一下add_all方法,在批量提交的时候,可以分批讲行提交
    def add_all(self, records):
        '''
        指添加记录
        :param records:
        :return:
        '''

        if len(records) == 0:
            return

        post_count = 10000
        record_count = len(records)
        post = math.ceil(record_count / post_count)

        for i in range(post):
            begin_index = i * post_count
            if i + 2 <= post:
                end_index = (i + 1) * post_count
            else:
                end_index = record_count

            # TODO 暂时先这么处理 解决不能重复提交的问题
            self.session.identity_map._dict = {}

            self.session.add_all(records[begin_index:end_index])
            self.save()

    def add(self, record):
        self.session.add(record)

    def save(self):
        try:
            self.session.commit()
        except Exception as e:
            self.session.rollback()
            print(e)

    # 执行sql语句
    def execute_ext(self, sql):
        return self.session.execute(sql)

    # 返加是数据 []
    def execute(self, sql):
        try:
            return self.session.execute(sql).fetchall()
        except Exception as e:
            self.session.rollback()

    # 返回一条数据元组()
    def oneexecute(self, sql):
        try:
            return self.session.execute(sql).first()
        except Exception as e:
            self.session.rollback()

    def query(self, query):
        return self.session.query(query)

    def close(self):
        self.session.close()

新建表:在oracle中创建数据表(table1)

  • 大家注意表中并没有给定主键
create table table1
(
  name1 VARCHAR2(50),
  name2 VARCHAR2(50),
  name3 VARCHAR2(50)
)

生成models

  • primary_key=True 赋给表中任一字段,我这里给的是 name1 这一步是必须要做的,name1这个字段不能为空值,如果办空,就不能保存数据。
from sqlalchemy import Column, DateTime, Numeric, String
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()
metadata = Base.metadata


class Table1(Base):
    __tablename__ = 'Table1'
    # 把 primary_key=True 给任意一个字段
    name1 = Column(String(50), primary_key=True)
    name2 = Column(String(50))
    name3 = Column(String(50))

如果没有主键的情况下,如果向表中添加数据,如果不是分批提交,那么基本上是没有问题,如果向我上面代码中要分批提交数据,如果第二批数据中被设为key字段有重复值,导致数据提交不上去。
我们可以在第一次提交之前加上 self.session.identity_map._dict = {} 这句代码就可以成功提交

def add_all(self, records):
        '''
        指添加记录
        :param records:
        :return:
        '''

        if len(records) == 0:
            return

        post_count = 10000
        record_count = len(records)
        post = math.ceil(record_count / post_count)

        for i in range(post):
            begin_index = i * post_count
            if i + 2 <= post:
                end_index = (i + 1) * post_count
            else:
                end_index = record_count

            # TODO 暂时先这么处理 解决不能重复提交的问题
            self.session.identity_map._dict = {}

            self.session.add_all(records[begin_index:end_index])
            self.save()

测试

dbsession =Connect(engine_oarcle)

for i in range(10000):
    record = Table1()
    record.name1 = "Name_" + str(i)
    record.name2 = "Name2_" + str(i)
    record.name3 = "Name3_" + str(i)
    records.append(record)

for i in range(10000):
    record = Table1()
    record.name1 = "Name_" + str(i)
    record.name2 = "Name2_" + str(i)
    record.name3 = "Name3_" + str(i)
    records.append(record)


for i in range(10000):
    record = Table1()
    record.name1 = "Name_" + str(i)
    record.name2 = "Name2_" + str(i)
    record.name3 = "Name3_" + str(i)
    records.append(record)

   dbsession.add_all(records)

如果没有加 self.session.identity_map._dict = {}会报如下错误

New instance <Table1 at 0x18c8771bda0> with identity key (<class '__main__.Table1'>, ('Name_0',), None) conflicts with persistent instance <Table1 at 0x18c846b5a58>
New instance <Table1 at 0x18c8826f278> with identity key (<class '__main__.Table1'>, ('Name_0',), None) conflicts with persistent instance <Table1 at 0x18c846b5a58>

猜你喜欢

转载自blog.csdn.net/weixin_39956308/article/details/82381920