尝试将我早期项目的数据库迁移到云端。虽然构建所有内容的代码都很糟糕,但数据库结构和数据本身相当可靠。我可能会想出一个转储方法来迁移所有内容(pgdump等),但我还有很多东西要学,所以我宁愿一步一步地做。
来源:~1gb sqlite数据库文件
**目标:**运行Postgres v9.6的Google CloudSQL
已经在云数据库中创建了表,使用与sqlite数据库相同的模式和表名。不担心模式强制错误,因为我还没有在云中定义外键。
计划:创建不同的,并发的SQLAlchemy连接到每个数据库,然后读取sqlite -->写入CloudSQL。返回并使用SQLAlchemy定义每个表的数据结构。Sniffy来自models.py:
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base, declared_attr
Base = declarative_base()
class PublicMixin(object):
@declared_attr
def __tablename__(cls):
return cls.__name__.lower()
class Category(PublicMixin, Base):
id = Column(Integer, primary_key=True)
name = Column(String)
class Player(PublicMixin, Base):
id = Column(Integer, primary_key=True)
name = Column(String)
username = Column(String)
notes = Column(String)
[...]
字符串
然后,我将此文件复制为models_lite.py,这样我就可以导入每个模型而不会受到干扰。下面是我尝试运行的migration.py文件,作为概念验证:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from models import Base, Category, Player
from models_sqlite import Base as Base_lite, Category as Category_lite, Player as Player_lite
# SQLite db
engine_lite = create_engine('sqlite:///mydb.sqlite')
Base_lite.metadata.bind = engine_lite
LiteSession = sessionmaker()
LiteSession.bind = engine_lite
session_lite = LiteSession()
# CloudSQL, via local proxy
engine_cloud = create_engine('postgresql+psycopg2://USER:PW@/DBNAME?host=/cloudsql/INSTANCE')
Base.metadata.bind = engine_cloud
CloudSession = sessionmaker()
CloudSession.bind = engine_cloud
session_cloud = CloudSession()
category_lite = session_lite.query(Category_lite).all()
category_cloud = Category()
for c in category_lite:
category_cloud = c
session_cloud.add(category_cloud)
session_cloud.commit()
型
运行此命令会产生以下错误:
File "postgres migration.py", line 68, in <module>
session_cloud.add(category_cloud)
[...]
sqlalchemy.exc.InvalidRequestError: Object '<Category at 0x11141b908>' is already attached to session '1' (this is '2')
型
在for
循环中显式地设置每一列是可行的(即:category_cloud.id = c.id
),但必须有一种方法来避免对每个表中的每一列都这样做。
2条答案
按热度按时间2q5ifsrm1#
使用sqlalchemy核心比使用SQL Server更容易实现这种数据传输操作。如果数据库数据只是要立即写入另一个数据库,那么在这里将数据库数据Map到对象是没有好处的,它只会增加复杂性并减慢速度。下面的代码将遍历Base中的每个表,选择sqlite数据库中的所有列,并将它们一次一个表地写入云数据库。
字符串
oxiaedzo2#
SQLAlchemy 1.4及更高版本:
字符串