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

596   1  

1 ответ:

Один из способов, который работает, по крайней мере, в некоторых случаях:

  1. Используйте column_descriptions объекта запроса, чтобы получить некоторую информацию о Столбцах в результирующем наборе.

  2. С помощью этой информации вы можете построить схему для создания новой таблицы в другой базе данных.

  3. Выполните запрос в исходной базе данных и вставьте результаты в новую таблицу.

Сначала некоторые настройки для примера:

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

    Ничего не найдено.