2017-11-23 3 views
0

同じモデルを共有する2つのデータベース間でデータを移行したいと考えています。ここに私のコードは次のとおりです。同じモデルを使用する異なるデータベース間でデータを移行するにはどうすればよいですか?

from sqlalchemy import create_engine, Column, Integer, String 
from sqlalchemy.ext.declarative import declarative_base 
from sqlalchemy.orm import sessionmaker 

Base = declarative_base() 


class Person(Base): 
    __tablename__ = 'person' 
    id = Column(Integer, primary_key=True) 
    name = Column(String(250), nullable=False) 


# Create engines 
source_engine = create_engine('sqlite:///source.db') 
mirror_engine = create_engine('sqlite:///mirror.db') 

# Create tables 
Base.metadata.create_all(bind=source_engine) 
Base.metadata.create_all(bind=mirror_engine) 

# Create sessions 
SourceSession = sessionmaker(bind=source_engine) 
source_session = SourceSession() 
MirrorSession = sessionmaker(bind=mirror_engine) 
mirror_session = MirrorSession() 

# Add data 
source_session.add(Person(name="James")) 
source_session.commit() 

# Migrate data 
results = source_session.query(Person).all() 
for row in results: 
    mirror_session.add(row) # This line produces an error 
mirror_session.commit() 

# Close sessions 
source_session.close() 
mirror_session.close() 

移行ラインmirror_session.add(row)は、次のエラーを生成します。

sqlalchemy.exc.InvalidRequestError: Object '<Person at 0x280a6b29898>' is already attached to session '1' (this is '2') 

答えて

0

は予想通り、あなたはそれを追加することができ、すべてのセッション情報を削除するためにmake_transient()を使用してください。

from sqlalchemy.orm import make_transient 

results = source_session.query(Person).all() 
for row in results: 
    mirror_session.add(make_transient(row)) 
mirror_session.commit() 
1

あなたの本当のユースケースは、SQLiteのではないかもしれませんが、それがある場合には、あなたはattached databasesとPythonで往復することなく、このような移行を行うことができます。

from sqlalchemy import create_engine, MetaData, event 
from sqlalchemy import Table, Column, Integer, String 

metadata = MetaData() 

person = Table('person', metadata, 
       Column('id', Integer, primary_key=True), 
       Column('name', String(250), nullable=False)) 

doppelganger = person.tometadata(metadata, schema='mirror') 

def attach_mirror(dbapi_conn, connection_rec): 
    dbapi_conn.execute("attach database 'mirror.db' as mirror") 

engine = create_engine('sqlite:///source.db') 
event.listen(engine, 'connect', attach_mirror) 

metadata.create_all(engine) 

with engine.connect() as conn: 
    conn.execute(person.insert().values(name='James')) 
    conn.execute(doppelganger.insert().prefix_with('OR IGNORE'). 
       from_select(doppelganger.c, person.select())) 
関連する問題