Подтвердить что ты не робот

База данных "на лету" со сценарием

У меня есть набор файлов .csv, которые я хочу обработать. Было бы намного проще обрабатывать его с помощью SQL-запросов. Интересно, есть ли какой-нибудь способ загрузить CSV файл и использовать язык SQL, чтобы изучить его с помощью языка сценариев, такого как python или ruby. Загрузка его с чем-то похожим на ActiveRecord была бы потрясающей.

Проблема в том, что я не хочу запускать базу данных где-то до запуска моего script. У меня не было дополнительных установок, необходимых вне языка сценариев и некоторых модулей.

Мой вопрос в том, какой язык и какие модули следует использовать для этой задачи. Я огляделся и не мог найти ничего, что бы соответствовало моей потребности. Возможно ли это?

4b9b3361

Ответ 1

Здесь sqlite3, включенный в python. С его помощью вы можете создать базу данных (в памяти) и добавить к ней строки и выполнить SQL-запросы.

Если вам нужна аккуратная функция ActiveRecord, вы должны добавить внешний ORM, например sqlalchemy. Это отдельная загрузка, хотя

Быстрый пример с использованием sqlalchemy:

from sqlalchemy import create_engine, Column, String, Integer, MetaData, Table
from sqlalchemy.orm import mapper, create_session
import csv
CSV_FILE = 'foo.csv'
engine = create_engine('sqlite://') # memory-only database

table = None
metadata = MetaData(bind=engine)
with open(CSV_FILE) as f:
    # assume first line is header
    cf = csv.DictReader(f, delimiter=',')
    for row in cf:
        if table is None:
            # create the table
            table = Table('foo', metadata, 
                Column('id', Integer, primary_key=True),
                *(Column(rowname, String()) for rowname in row.keys()))
            table.create()
        # insert data into the table
        table.insert().values(**row).execute()

class CsvTable(object): pass
mapper(CsvTable, table)
session = create_session(bind=engine, autocommit=False, autoflush=True)

Теперь вы можете запрашивать базу данных, фильтровать любое поле и т.д.

Предположим, что вы запустили код выше на этом csv:

name,age,nickname
nosklo,32,nosklo
Afila Tun,32,afilatun
Foo Bar,33,baz

Это создаст и заполнит таблицу в памяти полями name, age, nickname. Затем вы можете запросить таблицу:

for r in session.query(CsvTable).filter(CsvTable.age == '32'):
    print r.name, r.age, r.nickname

Это автоматически создаст и запустит запрос SELECT и вернет правильные строки.

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

Ответ 2

Используйте БД в библиотеке, например SQLite. Есть Python и Ruby версии.

Загрузите CSV в таблицу, там могут быть модули/библиотеки, которые тоже помогут вам здесь. Затем SQL прочь.

Ответ 3

Посмотрел Perl и и текст:: CSV и DBI? В CPAN есть много модулей, чтобы сделать именно это. Вот пример (из ЗДЕСЬ):

#!/usr/bin/perl
use strict;
use warnings;
use DBI;

# Connect to the database, (the directory containing our csv file(s))

my $dbh = DBI->connect("DBI:CSV:f_dir=.;csv_eol=\n;");

# Associate our csv file with the table name 'prospects'

$dbh->{'csv_tables'}->{'prospects'} = { 'file' => 'prospects.csv'};

# Output the name and contact field from each row

my $sth = $dbh->prepare("SELECT * FROM prospects WHERE name LIKE 'G%'");
$sth->execute();
while (my $row = $sth->fetchrow_hashref) {
     print("name = ", $row->{'Name'}, "  contact = ", $row->{'Contact'}. "\n");
}
$sth->finish();

name = Glenhuntly Pharmacy  contact = Paul
name = Gilmour Shoes  contact = Ringo

Просто введите perldoc DBI и perldoc Text:: CSV в командной строке для большего.

Ответ 4

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

Ответ 5

Вы можете использовать язык сценариев для анализа файла CSV и хранения данных в SQLite, который использует только один файл для место хранения. Оттуда вы имеете его в базе данных и можете запускать запросы против него.

В качестве альтернативы, в Windows вы можете настроить источник данных ODBC как файл CSV. Но автоматизировать это может быть сложно.

Ответ 6

Я использовал решение nosklo (спасибо!), но у меня уже был первичный ключ (переданный как pk_col) в строке столбца (первая строка csv). Поэтому я решил поделиться своей модификацией. Я использовал троицу.

table = Table(tablename, metadata,
    *((Column(pk_col, Integer, primary_key=True)) if rowname == pk_col else (Column(rowname, String())) for rowname in row.keys()))
table.create()

Ответ 7

PHP FlatfileDB доступен здесь - очень хороший вариант, если вы создаете веб-приложение