2016-05-20 2 views
4
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()) 

предположив у нас есть объекты кино:экономии Объемные сложные объекты SQLAlchemy

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") 

как мы Bulk сохранить это в 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 к сеансу индивидуально? Объемная вставка будет лучше, но я не понимаю, почему данные не сохраняются, если это делается.

+0

Не удается полностью сохранить его, или сами экземпляры ShowTime сами сохраняются, но не имеют соответствующих данных. По-видимому, ['bulk_save_objects'] (http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.bulk_save_objects) является довольно низким API уровня и игнорирует много вещей, как отношения. Вы посмотрели ['Session.add_all'] (http://docs.sqlalchemy.org/en/latest/orm/session_api.html#sqlalchemy.orm.session.Session.add_all)? –

+0

@ IljaEverilä Думаю, я не упоминал об этом. но да 'Showtime' сохраняется, но« отношения »игнорируются. – halcyonjuly7

ответ

5

- API слишком низкого уровня для вашего прецедента, в котором сохраняются несколько объектов модели и их отношения. Документация ясно по этому вопросу:

Предупреждение

Основная функция позволяет сохранить для более низкой латентностью INSERT/UPDATE строк за счет большинства других функций блок-оф-работы. Такие функции, как управление объектами, управление отношениями и поддержка предложения SQL - это молча пропущено в пользу сырых INSERT/UPDATES записей.

Перед использованием этого метода прочитайте список предостережений в Bulk Operations и полностью проверьте и подтвердите функциональность всего кода, разработанного с использованием этих систем.

Вы должны использовать Session.add_all(), чтобы добавить коллекцию экземпляров к сеансу. Он будет обрабатывать экземпляры по одному, но это цена, которую вы должны заплатить за расширенные функции, такие как обработка отношений.

Таким образом, вместо

session.bulk_save_objects(showtime_lists) 
session.commit() 

сделать

session.add_all(showtime_lists) 
session.commit() 
+0

Ну, это то, что я получаю за простое сканирование документов, а не их полное чтение. Я ценю вас, выделяя эту часть. Я даже планировал сделать это с помощью ядра SQLAlchemy, но, видя, что отношения довольно сложны .. ну ... 'Session.add_all' это – halcyonjuly7

0

Вы можете присвоить идентификаторы вручную:

  1. Получить write lock на столе

  2. Fin d самый высокий существующий идентификатор

  3. вручную генерировать возрастающую последовательность идентификаторов

Вместо фиксирующих таблицу, вы можете быть в состоянии увеличивать последовательность ID в базе данных для "reserve" a block of ids.

Вам необходимо вставить правильный порядок, чтобы избежать нарушений внешнего ключа (или отложить ограничения, если это позволяет ваш движок).

Смежные вопросы