批量保存复杂对象SQLAlchemy

时间:2016-05-20 04:39:18

标签: python sqlalchemy flask-sqlalchemy

association_table = Table("association_table",
                          Base.metadata,
                          Column("show_id", Integer(), ForeignKey("show_times.id"), primary_key=True),
                          Column("theater_id", Integer(), ForeignKey("theaters.id")))

association_table2 = Table("association_table2",
                           Base.metadata,
                           Column("show_id", Integer(), ForeignKey("show_times.id"), primary_key=True),
                           Column("movie_id", Integer(), ForeignKey("movies.id")))



class Movie(Base):
    __tablename__ = "movies"
    id = Column(Integer, primary_key=True)
    title = Column(String(), unique=True)
    plot = Column(String())
    duration = Column(String())
    rating = Column(String())
    trailer = Column(String())
    imdb = Column(String())
    poster = Column(String())
    summary = Column(String())

class Theater(Base):
    __tablename__ = "theaters"
    id = Column(Integer, primary_key=True)
    zip_code = Column(String())
    city = Column(String())
    state = Column(String())
    address = Column(String())
    phone_number = Column(String())


class Showtime(Base):
    __tablename__ = "show_times"
    id = Column(Integer, primary_key=True)
    date = Column(Date())
    theaterz = relationship("Theater", secondary=association_table)
    moviez = relationship("Movie", secondary=association_table2)
    showtimes = Column(String())

假设我们有电影对象:

movie_1 = Movie(title="Cap Murica",
              plot="Cap punches his way to freedom",
              duration="2 hours")

movie_2 = Movie(title="Cap Murica 22222",
              plot="Cap punches his way to freedom again",
              duration="2 hours")

和剧院对象:

theater = Theater(name="Regal Cinemas",
                  zip_code="00000",
                  city="Houston",
                  state="TX")

我们如何将其批量保存到show_times模型中?

我试过这样做:

movies = [movie_1, movie_2] # these movie objects are from the code snippet above

show_times = Showtime(date="5/19/2016",
                      theaterz=[theater],
                      moviez=movies)
session.add(show_times)
session.commit()

欢呼上述作品。但是当我像这样批量做的时候:

showtime_lists = [show_time1, show_time2, showtime3] # these are basically just the same show time objects as above

session.bulk_save_objects(showtime_lists)
session.commit()

它不会失败,但数据也不会持久存储到数据库中。

我的意思是,是否可以单独向会话添加每个show_time?批量插入会更好,但我不明白为什么如果这样做,数据不会持久存在。

2 个答案:

答案 0 :(得分:14)

Session.bulk_save_objects()对于您的用例来说是太低级别的API,它会持久存储多个模型对象及其关系。文档清楚明了:

  

警告

     

批量保存功能允许以较低延迟的行INSERT / UPDATE为代价,而牺牲了大多数其他工作单元功能。对象管理,关系处理和SQL子句支持等功能默默省略,支持原始INSERT / UPDATES记录。

     

在使用此方法之前,请阅读Bulk Operations处的警告列表,并完全测试并确认使用这些系统开发的所有代码的功能。

您应该使用Session.add_all()向会话添加实例集合。它将一次处理一个实例,但这是您必须为高级功能(如关系处理)支付的价格。

所以,而不是

session.bulk_save_objects(showtime_lists)
session.commit()

DO

session.add_all(showtime_lists)
session.commit()

答案 1 :(得分:0)

您可以手动分配ID:

  1. 在桌面上获取write lock

  2. 查找现有最高ID

  3. 手动生成不断增加的ID序列

  4. 您可以将数据库中的id序列增加到"reserve" a block of ids,而不是锁定表。

    您必须以正确的顺序插入以避免外键违规(或者如果引擎允许,则推迟约束)。