Есть ли способ восстановить старые данные для таблицы после изменения ее определения в sqlalchemy? - PullRequest
0 голосов
/ 24 марта 2019

Скажем, есть файл movie.py, который содержит определение таблицы для фильма и базы, например

# base.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
engine = create_engine('postgresql://usr:pass@localhost:5432/sqlalchemy')
Session = sessionmaker(bind=engine)
Base = declarative_base()
# move.py
from sqlalchemy import Column, String, Integer, Date
from base import Base
class Movie(Base):
    __tablename__ = 'movies'

    id = Column(Integer, primary_key=True)
    title = Column(String)
    release_date = Column(Date)

    def __init__(self, title, release_date):
        self.title = title
        self.release_date = release_date

И вставить несколько запросов, таких как

# coding=utf-8
from datetime import date
from base import Session, engine, Base
from movie import Movie

# 2 - generate database schema
Base.metadata.create_all(engine)

# 3 - create a new session
session = Session()

# 4 - create movies
bourne_identity = Movie("The Bourne Identity", date(2002, 10, 11))
furious_7 = Movie("Furious 7", date(2015, 4, 2))
pain_and_gain = Movie("Pain & Gain", date(2013, 8, 23))

# 5 - persists data
session.add(bourne_identity)
session.add(furious_7)
session.add(pain_and_gain)


# 10 - commit and close session
session.commit()
session.close()

Есть ли способ восстановить старые данные, которые я вставил, если бы я получил новое определение для моей таблицы фильмов (добавьте больше столбцов в файл move.py)?

1 Ответ

0 голосов
/ 24 марта 2019

Вы хотели спросить "как мне обновить схему базы данных существующей базы данных?". Это называется «миграция схемы». Есть несколько способов атаковать это. Самый простой способ - заставить SqlAlchemy работать в другом направлении ... заставить его генерировать метаданные схемы из существующей базы данных вместо создания метаданных, а затем с помощью SqlAlchemy создать базу данных из этого. Это называется Отражение . Вы сделаете это, затем выполните отдельные команды для обновления схемы базы данных. При этом вам нужно будет учитывать, что произойдет с существующими строками в вашей таблице при внесении этих изменений. Вы по-прежнему будете использовать определение объекта домена (объект Movie), но не будете использовать create_all (). create_all () игнорирует любые таблицы, которые уже существуют.

На самом деле, это быстро усложняется, поэтому вам обычно нужно использовать стратегию переноса формальной схемы и, возможно, пакет поддержки для этого. Собственная документация SqlAlchemy рекомендует для этого два пакета. Смотрите эту страницу:

https://docs.sqlalchemy.org/en/latest/core/metadata.html

Немного прокрутите вниз до раздела «Изменение схем путем миграции».

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...