SQLAlchemy-копирование схемы и данных подзапроса в другую базу данных
Я пытаюсь скопировать данные из подзапроса из postgres (from_engine) в базу данных sqlite. Я могу добиться этого для копирования таблицы, используя следующую команду:
smeta = MetaData(bind=from_engine)
table = Table(table_name, smeta, autoload=True)
table.metadata.create_all(to_engine)
Однако я не уверен, как добиться того же для оператора подзапроса.
- Сандип
Править:
Следите за ответом. После того, как я создал таблицу, я хочу создать подзапрос stmt следующим образом:
table = Table("newtable", dest_metadata, *columns)
stmt = dest_session.query(table).subquery();
Правда, последние инструкции, заканчивается с ошибкой
указатель.инструкция EXECUTE, параметры)
с SQLAlchemy.экскавация.ProgrammingError: (ProgrammingError) отношение "newtable" не существует
Строка 3: FROM newtable) как anon_1
1 ответ:
Один из способов, который работает, по крайней мере, в некоторых случаях:
Используйте
column_descriptionsобъекта запроса, чтобы получить некоторую информацию о Столбцах в результирующем наборе.С помощью этой информации вы можете построить схему для создания новой таблицы в другой базе данных.
Выполните запрос в исходной базе данных и вставьте результаты в новую таблицу.
Сначала некоторые настройки для примера:
from sqlalchemy import create_engine, MetaData, from sqlalchemy import Column, Integer, String, Table from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker # Engine to the database to query the data from # (postgresql) source_engine = create_engine('sqlite:///:memory:', echo=True) SourceSession = sessionmaker(source_engine) # Engine to the database to store the results in # (sqlite) dest_engine = create_engine('sqlite:///:memory:', echo=True) DestSession = sessionmaker(dest_engine) # Create some toy table and fills it with some data Base = declarative_base() class Pet(Base): __tablename__ = 'pets' id = Column(Integer, primary_key=True) name = Column(String) race = Column(String) Base.metadata.create_all(source_engine) sourceSession = SourceSession() sourceSession.add(Pet(name="Fido", race="cat")) sourceSession.add(Pet(name="Ceasar", race="cat")) sourceSession.add(Pet(name="Rex", race="dog")) sourceSession.commit()Теперь к интересному бит:
# This is the query we want to persist in a new table: query= sourceSession.query(Pet.name, Pet.race).filter_by(race='cat') # Build the schema for the new table # based on the columns that will be returned # by the query: metadata = MetaData(bind=dest_engine) columns = [Column(desc['name'], desc['type']) for desc in query.column_descriptions] column_names = [desc['name'] for desc in query.column_descriptions] table = Table("newtable", metadata, *columns) # Create the new table in the destination database table.create(dest_engine) # Finally execute the query destSession = DestSession() for row in query: destSession.execute(table.insert(row)) destSession.commit()Должны быть более эффективные способы сделать последний цикл. Но массовая вставка-это уже другая тема.
Comments