Использование SQLAlchemy для миграции баз данных (sqlite в Postgres CloudSQL)Python

Программы на Python
Anonymous
Использование SQLAlchemy для миграции баз данных (sqlite в Postgres CloudSQL)

Сообщение Anonymous »

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

Источник: файл базы данных sqlite размером около 1 ГБ

Назначение: Google CloudSQL запуск Postgres v9.6

Уже создал таблицы в облачной базе данных, используя ту же схему и имена таблиц, что и в базе данных sqlite. Не беспокоюсь об ошибках принудительного применения схемы, поскольку я еще не определил внешние ключи в облаке.

План: Создание отдельных параллельных соединений SQLAlchemy. в каждую базу данных, затем прочитайте sqlite -> напишите в CloudSQL. Вернулся и определил структуры данных для каждой таблицы с помощью SQLAlchemy. Фрагмент из models.py:

Код: Выделить всё

from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base, declared_attr

Base = declarative_base()

class PublicMixin(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()

class Category(PublicMixin, Base):
id = Column(Integer, primary_key=True)
name = Column(String)

class Player(PublicMixin, Base):
id = Column(Integer, primary_key=True)
name = Column(String)
username = Column(String)
notes = Column(String)
[...]
Затем я продублировал этот файл как models_lite.py, чтобы можно было импортировать каждую модель без каких-либо помех. Вот файл migration.py, который я пытался запустить в качестве доказательства концепции:

Код: Выделить всё

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Base, Category, Player
from models_sqlite import Base as Base_lite, Category as Category_lite, Player as Player_lite

# SQLite db
engine_lite = create_engine('sqlite:///mydb.sqlite')
Base_lite.metadata.bind = engine_lite
LiteSession = sessionmaker()
LiteSession.bind = engine_lite
session_lite = LiteSession()

# CloudSQL, via local proxy
engine_cloud = create_engine('postgresql+psycopg2://USER:PW@/DBNAME?host=/cloudsql/INSTANCE')
Base.metadata.bind = engine_cloud
CloudSession = sessionmaker()
CloudSession.bind = engine_cloud
session_cloud = CloudSession()

category_lite = session_lite.query(Category_lite).all()
category_cloud = Category()

for c in category_lite:
category_cloud = c
session_cloud.add(category_cloud)

session_cloud.commit()
При запуске возникает следующая ошибка:

Код: Выделить всё

File "postgres migration.py", line 68, in 
session_cloud.add(category_cloud)
[...]
sqlalchemy.exc.InvalidRequestError: Object '' is already attached to session '1' (this is '2')
Явная установка каждого столбца внутри цикла for работает (т. е.: Category_cloud.id = c.id), но должен быть способ чтобы избежать необходимости делать это для каждого столбца в каждой таблице. Как мне к этому подойти?

Подробнее здесь: https://stackoverflow.com/questions/557 ... s-cloudsql

Вернуться в «Python»