如何生成各种数据库转储

时间:2010-11-08 06:13:29

标签: python database csv mysqldump

我有一个CSV文件,想要为sqlite,mysql,postgres,oracle和mssql生成数据转储。

是否有通用的API(理想情况下是基于Python的)?

我可以使用ORM将数据插入每个数据库,然后导出转储,但这需要安装每个数据库。这似乎也浪费资源 - 这些CSV文件 BIG

由于每个数据库的变化,我对自己尝试编写SQL很谨慎。理想情况下,有人已经完成了这项艰苦的工作,但我还没有找到它。

3 个答案:

答案 0 :(得分:5)

SQLAlchemy是一个数据库库(以及ORM functionality)支持您提及的所有不同数据库的SQL generation中的dialects(以及更多)。< / p>

在正常使用中,您可以创建SQL表达式/指令(使用schema.Table object),创建database engine,然后将指令绑定到引擎,以生成SQL。

然而,发动机并非严格必要;每个方言都有一个compiler,可以在没有连接的情况下生成SQL;唯一需要注意的是,你需要阻止它生成绑定参数,就像默认情况下那样:

from sqlalchemy.sql import expression, compiler
from sqlalchemy import schema, types
import csv

# example for mssql
from sqlalchemy.dialects.mssql import base
dialect = base.dialect()
compiler_cls = dialect.statement_compiler
class NonBindingSQLCompiler(compiler_cls):
    def _create_crud_bind_param(self, col, value, required=False):
        # Don't do what we're called; return a literal value rather than binding
        return self.render_literal_value(value, col.type)

recipe_table = schema.Table("recipe", schema.MetaData(), schema.Column("name", types.String(50), primary_key=True), schema.Column("culture", types.String(50)))

for row in [{"name": "fudge", "culture": "america"}]: # csv.DictReader(open("x.csv", "r")):
    insert = expression.insert(recipe_table, row, inline=True)
    c = NonBindingSQLCompiler(dialect, insert)
    c.compile()
    sql = str(c)
    print sql

上面的例子确实有效;它假定您知道目标数据库表模式;它应该很容易适应从CSV导入并为多个目标数据库方言生成。

答案 1 :(得分:1)

我不是数据库向导,但是Python中的AFAIK并不是一个可以开箱即用的常见API。 PEP 249定义了一个API,应该由访问DB的模块使用,AFAIK至少使用MySQL和Postgre python模块(herehere),这可能是是一个起点。

我试图追随自己的道路 - 然而 - 将是另一条道路:

  1. 将CVS导入MySQL (这只是因为MySQL是我最熟悉的并且网上有大量材料,例如this very easy recipe,但你可以这样做从另一个数据库开始的相同程序。)
  2. 生成MySQL转储
  3. 处理MySQL转储文件,以便对其进行修改以符合SQLite(及其他)语法。
  4. 用于处理转储文件的脚本可能非常紧凑,但如果使用正则表达式解析行,它们可能会有些棘手。这是一个示例脚本MySQL→SQLite,我只是从this page粘贴:

    #!/bin/sh 
    mysqldump --compact --compatible=ansi --default-character-set=binary mydbname | 
    grep -v ' KEY "' | 
    grep -v ' UNIQUE KEY "' | 
    perl -e 'local $/;$_=<>;s/,\n\)/\n\)/gs;print "begin;\n";print;print "commit;\n"' | 
    perl -pe ' 
    if (/^(INSERT.+?)\(/) { 
    $a=$1; 
    s/\\'\''/'\'\''/g; 
    s/\\n/\n/g; 
    s/\),\(/\);\n$a\(/g; 
    } 
    ' | 
    sqlite3 output.db
    

    您可以在python中编写脚本(在这种情况下,您应该查看re.compile的性能)。

    我选择的理由是:

    1. 我通过 mysql
    2. 为我完成了繁重的[导入,因此数据一致性检查+生成启动SQL文件]
    3. 我只需要安装一个数据库。
    4. 我可以完全控制正在发生的事情以及微调过程的可能性。
    5. 我可以通过这样的方式构建我的脚本,以便将其扩展到其他数据库非常容易(基本上我会将其构建为识别单个字段的解析器+一组语法 - 每个数据库一个 - 我可以通过命令行选项选择)
    6. 关于SQL风格之间的差异,还有更多关于单个数据库导入/导出库的文档。
    7. 编辑:基于模板的方法

      如果由于任何原因你自己没有足够的信心自己编写SQL,你可以使用一种基于模板的脚本。我就是这样做的:

      1. 在您计划使用的所有4个数据库中导入并生成表的转储。
      2. 对于每个DB保存转储的初始部分(使用模式声明和所有其余部分)和单个插入指令。
      3. 编写一个python脚本 - 对于每个数据库导出 - 将输出转储的“标题”加上相同的“保存行”,您将以编程方式替换CVS文件中每行的值。
      4. 这种方法的明显缺点是您的“模板”仅适用于一个表。最强烈的一点是,编写这样的脚本非常简单快捷。

        HTH至少有点!

答案 2 :(得分:0)

你可以这样做 - Create SQL tables from CSV files

Generate Insert Statements from CSV file

或尝试此Generate .sql from .csv python

当然,您可能需要调整提到的脚本以满足您的需求。