回答

收藏

SQLAlchemy-将子查询的架构和数据复制到另一个数据库

技术问答 技术问答 424 人阅读 | 0 人回复 | 2023-09-14

我正在尝试将子查询中的数据postgres(from_engine)复制到sqlite数据库。我可以使用以下命令复制表来实现这一目的:+ q" z' K* }  [: E" p
smeta = MetaData(bind=from_engine)table = Table(table_name,smeta,autoload=True)table.metadata.create_all(to_engine)但是,我不确定如何为子查询句子实现相同的功能。$ q5 ]/ [2 |  c- f' j  w
-山迪普, U7 ~/ [! J+ ~9 B8 ?: u
编辑:跟进答案。创建表后,我要创建一个子查询stmt,如下所示:
8 r6 h( Y* O# @6 ?table = Table("newtable",dest_metadata,*columns)stmt = dest_session.query(table).subquery();但是,最后一个stmt最终出现了错误cursor.execute(statement,parameters)sqlalchemy.exc.ProgrammingError:(ProgrammingError)关系“% `, Z/ j8 o0 V# b5 W( K! }
newtable第三行不存在:FROM newtable)AS anon_1
1 O8 ~0 `) c) {% F. B1 u# X+ N3 |                                                               
  r! f4 e4 ?9 {# r8 j2 |    解决方案:                                                               
3 M' i4 I8 r( M! M" {9 d9 Q6 \  k                                                                至少在某些情况下:7 f3 ]1 \5 O. V3 r5 F: [4 }# M
[ol]使用column_descriptions查询对象获取各列相关结果的信息。6 v: c! g" ]) o0 w8 j4 m3 m
利用这些信息,您可以在另一个数据库中构建创建新表的模式。
" ?/ p2 F6 v9 {8 q/ J: b$ C运行查询源数据库,并将结果插入新表。
: L' q9 w/ T1 N6 b1 r8 ?[/ol]先设置示例:
4 M9 [) p' _7 J0 e( dfrom sqlalchemy import create_engine,MetaData,from sqlalchemy import Column,Integer,String,Tablefrom sqlalchemy.ext.declarative import declarative_basefrom 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 dataBase = 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()现在去有趣的地方:! L8 D3 X# Z7 Y: k, i& e) x
# 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 databasetable.create(dest_engine)# Finally execute the querydestSession = DestSession()for row in query:    destSession.execute(table.insert(row))destSession.commit()最后一个一个循环应该有更有效的方法。但批量插入是另一个主题。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则