【问题标题】:How do I migrate rows from a local SQLite DB to a remote MySQL DB using SQLAlchemy?如何使用 SQLAlchemy 将行从本地 SQLite DB 迁移到远程 MySQL DB?
【发布时间】:2018-09-29 10:26:00
【问题描述】:

我正在使用 SQLAlchemy 管理 2 个数据库。一个是本地 SQLite 数据库,另一个是谷歌云平台上的远程 MySQL 数据库,它们共享相同的架构。我正在尝试使用将 SQLite DB 中包含的行附加到 MySQL DB。我目前有一个文件这样定义我的类:

SensorCollection.py

class Readings(Base):
    __tablename__ = 'readings'

    time = Column(String(250), primary_key=True)
    box_name = Column(String(250))
    FS = Column(Numeric)
    IS = Column(Numeric)
    VS = Column(Numeric)
    CO = Column(Numeric)
    TVOC = Column(Numeric)
    cTemp = Column(Numeric)
    fTemp = Column(Numeric)
    humidity = Column(Numeric)
    pressure = Column(Numeric)

然后我有另一个文件声明了我的 Base、Session 和引擎:

base.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///%s' % 'db/db.db')
Session = sessionmaker(bind=engine)
Base = declarative_base()

最后是我的实际代码:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.schema import Table
from SensorCollection import Readings
from sqlalchemy.sql.expression import insert

# uploads MySQL database to Google cloud server
# uses ORM to ensure the databases can communicate with each other
user = ***
password = ***
host = ***
port = ***
dbName = ***
instanceConnectionName = ***
# create the engine for the local db
engineLocal = create_engine('sqlite:///%s' % 'db/db.db')
BaseLocal = Readings(None, None, None, None, None, None, None, None, None, None, None)

# create the engine for the Google db
engineGoogle = create_engine('mysql+mysqldb://%s@%s:%s/%s?unix_socket=/cloudsql/%s' % (user, host, port, dbName, instanceConnectionName))
SessionGoogle = sessionmaker(bind=engineGoogle)
BaseGoogle = Readings(None, None, None, None, None, None, None, None, None, None, None)

# create the local db
BaseLocal.metadata.create_all(engineLocal)

# create the Google db and start the session
BaseGoogle.metadata.create_all(engineGoogle)
sessionGoogle = SessionGoogle()

# create table objects for each db
t1 = Table('readings', BaseLocal.metadata, autoload=True, autoload_with=engineLocal)
t2 = Table('readings', BaseGoogle.metadata, autoload=True, autoload_with=engineGoogle)

# the first subquery, select all ids from SOME_TABLE where some_field is not NULL
s1 = t1.select()

# the second subquery, select all ids from SOME_TABLE where some_field is NULL
s2 = t2.select()

# union s1 and s2 subqueries together and alias the result as "alias_name"
q = s1.union(s2)

insert(t2, s1)
sessionGoogle.query(q)
# sessionGoogle.add_all(s1)

# commit changes and close the session
sessionGoogle.commit()
sessionGoogle.close()

目前,SQLite 数据库正常存在并且远程服务器已设置,但代码在连接到 Google 时甚至没有创建表。它似乎连接正确,因为如果我更改任何服务器详细信息,我会收到 MySQL 错误。它也没有给我任何错误。它编译并运行,但不附加数据甚至创建表。这是我第一次对任何类型的数据库进行破解,所以我确信它充满了错误,而且一点也不优雅。任何帮助将不胜感激。

编辑 djkern 帮助我创建了表格,并且我更新了我的代码。不过,我还没有得到要附加的数据。

【问题讨论】:

    标签: python mysql sqlite sqlalchemy google-cloud-platform


    【解决方案1】:

    在您的代码中,您有:

    # create the Google db and start the session
    BaseLocal.metadata.create_all(engineLocal)
    sessionGoogle = SessionGoogle()
    

    你的意思是这样吗?

    # create the Google db and start the session
    BaseGoogle.metadata.create_all(engineGoogle)
    sessionGoogle = SessionGoogle()
    

    【讨论】:

    • 哇。我觉得很傻。好吧,现在创建了表,但它是空的。尚未附加任何数据。感谢您朝着正确的方向迈出一步! +1
    【解决方案2】:

    还需要添加两个类,

    class ReadingsLocal(BaseLocal):
    

    class ReadingsGoogle(BaseGoogle):
    

    它们应该与

    在同一个文件中并且相同
    class Readings(Base):
    

    还必须创建新的 Base、engine 和 Session 变量。然后,代码应该是这样的:

    # create the local db
    BaseLocal.metadata.create_all(engineLocal)
    sessionLocal = SessionLocal()
    
    # create the Remote db and start the session
    BaseGoogle.metadata.create_all(engineGoogle)
    sessionGoogle = SessionGoogle()
    
    for reading in sessionLocal.query(ReadingsLocal):
        # reading is already attached to a session, so a tmp variable must be created to avoid conflicts
        tmp = ReadingsGoogle(reading.time, reading.box_name, reading.FS, reading.IS, reading.VS, reading.CO, reading.TVOC,
                   reading.cTemp, reading.fTemp, reading.humidity, reading.pressure)
        sessionGoogle.add(tmp)
    
    # commit changes and close the session
    sessionGoogle.commit()
    sessionGoogle.close()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-17
      • 2022-01-17
      • 2014-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多