как генерировать различные дампы базы данных - PullRequest
2 голосов
/ 08 ноября 2010

У меня есть файл CSV, и я хочу создать дампы данных для sqlite, mysql, postgres, oracle и mssql.

Существует ли общий API (в идеале основанный на Python) для этого?*

Я мог бы использовать ORM для вставки данных в каждую базу данных, а затем экспортировать дампы, однако это потребовало бы установки каждой базы данных.Это также кажется пустой тратой ресурсов - эти CSV-файлы BIG .

Я опасаюсь пытаться самостоятельно создавать SQL из-за различий в каждой базе данных.В идеале кто-то уже проделал эту тяжелую работу, но я еще не нашел ее.

Ответы [ 3 ]

5 голосов
/ 24 ноября 2010

SQLAlchemy - это библиотека базы данных, которая (а также функциональность ORM ) поддерживает генерацию SQL на диалектах всехразличные базы данных, о которых вы упоминаете (и не только).

При обычном использовании вы можете создать выражение / инструкцию SQL (используя schema.Table object ), создать ядро ​​базы данных , а затем связать инструкцию с механизмом для генерации SQL.

Однако механизм не является строго необходимым;каждый из диалектов имеет компилятор , который может генерировать 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 голос
/ 22 ноября 2010

Я не мастер баз данных, но AFAIK в Python не имеет общего API, который бы делал из коробки то, что вы просите.Существует PEP 249 , который определяет API, который должен использоваться модулями, обращающимися к БД, и что AFAIK используется по крайней мере модулями Python MySQL и Postgre ( здесь и здесь ) и это, возможно, могло бы послужить отправной точкой.

Дорога, по которой я попытался бы пойти сам, - однако, была бы другой:

  1. Импортируйте CVS ntoMySQL (это просто потому, что MySQL - это тот, который я знаю лучше всего, и в сети есть тонны материала, как, например, этот очень простой рецепт , но вы можете выполнить ту же процедуру, начиная с другойбаза данных).
  2. Создание дампа MySQL .
  3. Обработка файла дампа MySQL для его изменения в соответствии с синтаксисом SQLite (и других).

Скрипты для обработки файла дампа могут быть очень компактными, хотя они могут быть сложными, если вы используете регулярное выражение для анализа строк.Вот пример скрипта MySQL → SQLite, который я просто вставил с этой страницы :

#!/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. Я получаю тяжелый [импорт и, следовательно, данныепроверки согласованности + генерация начального файла SQL], выполненные для меня mysql
  2. У меня должна быть установлена ​​только одна база данных.
  3. У меня есть полный контроль над тем, что происходит, ивозможность тонкой настройки процесса.
  4. Я могу структурировать свой сценарий таким образом, чтобы его было очень легко расширить для других баз данных (в основном я бы структурировал его как анализатор, который распознает отдельные поля + aнабор грамматик - по одной для каждой базы данных - которые я могу выбрать с помощью параметра командной строки)
  5. Документов о различиях между разновидностями SQL гораздо больше, чем об импорте / экспорте одной БДбиблиотеки ort.

РЕДАКТИРОВАТЬ: шаблонный подход

Если по какой-либо причине вы не чувствуете себя достаточно уверенно, чтобы написать SQL самостоятельно, вы можетеиспользовать своего рода скрипт на основе шаблона.Вот как я бы это сделал:

  1. Импортируйте и сгенерируйте дамп таблицы во всех 4 БД, которые вы планируете использовать.
  2. Для каждой БД сохраните начальную частьdump (с объявлением схемы и всем остальным) и одна инструкция вставки.
  3. Напишите скрипт на python, который - для каждого экспорта БД - будет выводить «заголовок» дампа плюс ту же «сохраненную строку»в котором вы будете программно заменять значения для каждой строки в вашем файле CVS.

Очевидным недостатком этого подхода является то, что ваш «шаблон» будет работать только для одной таблицы.Самое сильное в этом то, что написание такого скрипта было бы чрезвычайно легко и быстро.

HTH хотя бы немного!

0 голосов
/ 08 ноября 2010

Вы можете сделать это - Создать таблицы SQL из файлов CSV

или Создать операторы вставки из файла CSV

или попробуйте это Сгенерируйте .sql из .csv python

Конечно, вам может понадобиться настроить упомянутые скрипты в соответствии с вашими потребностями.

...