【发布时间】:2016-05-06 11:15:27
【问题描述】:
TL;DR
我想将数据从 MS SQL Server + ArcSDE 迁移到 PostgreSQL + PostGIS,最好使用 SQLAlchemy。
我正在使用 SQLAlchemy 1.0.11 将现有数据库从 MS SQL 2012 迁移到 PostgreSQL 9.2(计划升级到 9.5)。
我一直在阅读这方面的内容,并找到了几个不同的来源(Tyler Lesmann、Inada Naoki、Stefan Urbanek 和 Stefan Urbanek 和 Mathias Fussenegger),它们采用了类似的方法来完成这项任务:
- 连接到两个数据库
- 反映源数据库的表
- 遍历表并为每个表
- 在目标数据库中创建对等表
- 在源中获取行并将它们插入到目标数据库中
代码
这是一个使用上次参考代码的简短示例。
from sqlalchemy import create_engine, MetaData
src = create_engine('mssql://user:pass@host/database?driver=ODBC+Driver+13+for+SQL+Server')
dst = create_engine('postgresql://user:pass@host/database')
meta = MetaData()
meta.reflect(bind=src)
tables = meta.tables
for tbl in tables:
data = src.execute(tables[tbl].select()).fetchall()
if data:
dst.execute(tables[tbl].insert(), data)
我知道同时获取所有行是一个坏主意,可以使用迭代器或fetchmany 来完成,但这不是我现在的问题。
问题 1
所有四个示例都在我的数据库中失败。我得到的错误之一与NVARCHAR 类型的列有关:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) type "nvarchar" does not exist
LINE 5: "desigOperador" NVARCHAR(100) COLLATE "SQL_Latin1_General_C...
^
[SQL: '\nCREATE TABLE "Operators" (\n\t"idOperador" INTEGER NOT NULL, \n\t"idGrupo" INTEGER, \n\t"desigOperador" NVARCHAR(100) COLLATE "SQL_Latin1_General_CP1_CI_AS", \n\t"Rua" NVARCHAR(200) COLLATE "SQL_Latin1_General_CP1_CI_AS", \n\t"Localidade" NVARCHAR(200) COLLATE "SQL_Latin1_General_CP1_CI_AS", \n\t"codPostal" NVARCHAR(10) COLLATE "SQL_Latin1_General_CP1_CI_AS", \n\tdataini DATETIME, \n\tdataact DATETIME, \n\temail NVARCHAR(50) COLLATE "SQL_Latin1_General_CP1_CI_AS", \n\turl NVARCHAR(50) COLLATE "SQL_Latin1_General_CP1_CI_AS", \n\tPRIMARY KEY ("idOperador")\n)\n\n']
我从这个错误的理解是PostgreSQL没有NVARCHAR而是VARCHAR,应该是等价的。我认为 SQLAlchemy 会自动将它们都映射到其抽象层中的String,但在这种情况下它可能不会那样工作。
问题:我是否应该事先定义所有的类/表,例如在models.py 中,以避免这样的错误?如果是这样,它将如何与给定(或其他)工作流程集成?
事实上,这个错误是在运行 Urbanek 的代码时得到的,我可以在其中指定要复制的表。运行上面的示例,我会...
问题 2
MS SQL 安装是使用ArcSDE(空间数据库引擎)的地理数据库。出于这个原因,一些列是非默认几何类型。在 PostgreSQL 方面,我使用的是 PostGIS 2。
尝试复制具有这些类型的表时,我收到如下警告:
/usr/local/lib/python2.7/dist-packages/sqlalchemy/dialects/mssql/base.py:1791: SAWarning: Did not recognize type 'geometry' of column 'geom'
(type, name))
/usr/local/lib/python2.7/dist-packages/sqlalchemy/dialects/mssql/base.py:1791: SAWarning: Did not recognize type 'geometry' of column 'shape'
这些后面跟着另一个错误(这个错误实际上是在执行上面提供的代码时抛出的):
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) relation "SDE_spatial_references" does not exist
LINE 1: INSERT INTO "SDE_spatial_references" (srid, description, aut...
^
我认为它未能创建警告中提到的列,但是在需要这些列时在稍后的步骤中引发了错误。
问题:问题是上一个问题的扩展:如何使用自定义(或在其他地方定义)类型进行迁移?
我知道GeoAlchemy2 可以与 PostGIS 一起使用。 GeoAlchemy 支持 MS SQL Server 2008,但在这种情况下,我想我是 stuck with SQLAlchemy 0.8.4(也许没有那么好的功能)。另外,我发现here 可以使用 GeoAlchemy 定义的类型进行反射。但是,我的问题仍然存在。
可能相关
- https://stackoverflow.com/questions/34475241/how-to-migrate-from-mysql-to-postgressql-using-pymysql
- SqlAlchemy: export table to new database
- https://stackoverflow.com/questions/34956523/sqlalchemy-custom-column-type-use-bindparam-as-multiple-function-parameters
- SQLAlchemy Reflection Using Metaclass with Column Override
编辑
当我看到引用 我这个编辑错了:数据库确实在使用 ArcSDE。SDE_spatial_references 的错误时,我认为这可能与 ArcSDE 有关,因为同一台机器上也安装了 ArcGIS for Server。然后我了解到 MS SQL Server 也有一些Spatial Data Types,然后我确认是这种情况。
编辑 2
这里有一些我忘记包含的更多细节。
迁移不必使用 SQLAlchemy 完成。我认为这是个好主意,因为:
- 我更喜欢使用 Python
- 解决方案必须使用 FOSS
- 理想情况下,它应该是一种易于重现的方式,并且可以启动和等待
- 迁移后,我想使用 Alembic 进行进一步的架构迁移
我尝试过但失败的其他事情(现在不记得确切的原因,但如果有任何答案提到它们,我会再看一遍):
- 水壶
- 地热水壶
- ogr2ogr(仍在尝试这种方法)
数据库详情:
- 小型数据库,± 3 GB
- ± 40 表
- 有空间和非空间数据的表
- 两个数据库(SQL Server 和 PostgreSQL)位于运行 Windows Server 2008 的同一服务器中
- 停机时间没有大问题(最多 8 小时即可)
【问题讨论】:
-
您可以尝试在dba.stackexchange.com 上询问,那里可能会为您提供此类数据迁移的其他选项。 +1 不过,写得很好的问题。
-
@JorgeCampos 感谢您的评论。实际上,我没有考虑 DBA.SE。我在那里进行了快速搜索,似乎关于 SQLAlchemy 的点击量较少。不过,我应该要求迁移这个问题吗?奥布里加多!
-
我认为您应该在那里问这个问题,重点关注迁移数据,因为他们是此类场景的专家。只需提及您已经使用 SQLAlchemy 尝试过,看看他们是否有替代这种方法的方法。我认为你不需要要求迁移这个,因为它是一个与 SQLAlchemy 相关的完美编程问题。德纳达 :)
-
是否有特定要求表明此迁移应通过 SQLAlchemy 完成?您要迁移的数据有多大?您能否承受源数据库的任何停机时间,还是在迁移期间它需要处于活动状态?
-
@Cahit 谢谢您的提问。我知道这些是相关的,我没有解决它们。我已经编辑了我的问题以包含该信息(请参阅编辑 2)。
标签: sql-server postgresql sqlalchemy postgis data-migration