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

Как экспортировать базу данных MySQL в JSON?

Мне интересно экспортировать подмножество значений из базы данных MySQL в файл в формате JSON на диске.

Я нашел ссылку, которая говорит о возможном способе сделать это: http://www.thomasfrank.se/mysql_to_json.html

... но когда я использую метод с этой страницы, он работает, но с двумя проблемами:

1) Он возвращает только около 15 результатов, при этом последний резко прерывается (неполный). Мой стандартный запрос для этого возвращает около 4000 результатов, когда я просто запускаю его как SELECT name, email FROM students WHERE enrolled IS NULL Но когда я запускаю его как:

SELECT 
     CONCAT("[",
          GROUP_CONCAT(
               CONCAT("{name:'",name,"'"),
               CONCAT(",email:'",email,"'}")
          )
     ,"]") 
AS json FROM students WHERE enrolled IS NULL;

... как описано в ссылке, он возвращает только (как я упоминал) 15 результатов. (fwiw, я проверил эти результаты против 4000, которые я должен получить, и эти 15 совпадают с первыми 15 из 4000)

2) Кажется, что символы "escape" включены в фактический файл, когда я добавляю INTO OUTFILE '/path/to/jsonoutput.txt' FIELDS TERMINATED BY ',' в конец этого запроса. Таким образом, запятые в конечном итоге выглядят как "\", когда, очевидно, я просто хотел бы иметь запятые без \.

Любые идеи о том, как получить правильный вывод JSON из MySQL? (Либо используя этот метод, либо какой-либо другой метод)?

Спасибо!

4b9b3361

Ответ 1

Возможно, он задает слишком много MySQL, чтобы ожидать, что он будет создавать хорошо сформированный json непосредственно из запроса. Вместо этого рассмотрите возможность создания чего-то более удобного, например CSV (с помощью фрагмента INTO OUTFILE '/path/to/output.csv' FIELDS TERMINATED BY ',', который вы уже знаете), а затем преобразования результатов в json на языке со встроенной поддержкой для него, например, python или php.

Изменить пример python, используя прекрасный SQLAlchemy:

class Student(object):
    '''The model, a plain, ol python class'''
    def __init__(self, name, email, enrolled):
        self.name = name
        self.email = email
        self.enrolled = enrolled

    def __repr__(self):
        return "<Student(%r, %r)>" % (self.name, self.email)

    def make_dict(self):
        return {'name': self.name, 'email': self.email}



import sqlalchemy
metadata = sqlalchemy.MetaData()
students_table = sqlalchemy.Table('students', metadata,
        sqlalchemy.Column('id', sqlalchemy.Integer, primary_key=True),
        sqlalchemy.Column('name', sqlalchemy.String(100)),
        sqlalchemy.Column('email', sqlalchemy.String(100)),
        sqlalchemy.Column('enrolled', sqlalchemy.Date)
    )

# connect the database.  substitute the needed values.
engine = sqlalchemy.create_engine('mysql://user:[email protected]/database')

# if needed, create the table:
metadata.create_all(engine)

# map the model to the table
import sqlalchemy.orm
sqlalchemy.orm.mapper(Student, students_table)

# now you can issue queries against the database using the mapping:
non_students = engine.query(Student).filter_by(enrolled=None)

# and lets make some json out of it:
import json
non_students_dicts = ( student.make_dict() for student in non_students)
students_json = json.dumps(non_students_dicts)

Ответ 2

Если у вас есть Ruby, вы можете установить mysql2xxxx gem (а не драгоценный камень mysql2json, который является другим камнем):

$ gem install mysql2xxxx

а затем запустите команду

$ mysql2json --user=root --password=password --database=database_name --execute "select * from mytable" >mytable.json

Драгоценный камень также обеспечивает mysql2csv и mysql2xml. Это не так быстро, как mysqldump, но также не страдает от некоторых странностей mysqldump (например, только возможность удалять CSV с того же компьютера, что и сам сервер MySQL)

Ответ 3

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

Например, в php это просто, как

Изменить Добавлен материал соединения db. Нет ничего внешнего.

$sql = "select ...";
$db = new PDO ( "mysql:$dbname", $user, $password) ;
$stmt = $db->prepare($sql);
$stmt->execute();
$result = $stmt->fetchAll();

file_put_contents("output.txt", json_encode($result));

Ответ 4

Другая возможность - использование MySQL Workbench.

Существует опция экспорта JSON в контекстном меню браузера объектов и в меню сетки результатов.

Дополнительная информация о документации MySQL: экспорт и импорт данных.

Ответ 5

HeidiSQL позволяет также сделать это.

Выделите все данные на вкладке DATA или в наборе результатов запроса... затем щелкните правой кнопкой мыши и выберите опцию Export Grid Rows. Затем этот параметр позволяет экспортировать любую из ваших данных как JSON, прямо в буфер обмена или непосредственно в файл:

введите описание изображения здесь

Ответ 6

Другим решением, если вы используете Ruby, является запись соединения script в базу данных с помощью ActiveRecord. Сначала вам нужно установить его

gem install activerecord

# ruby ./export-mysql.rb
require 'rubygems'
require 'active_record'

ActiveRecord::Base.establish_connection(
  :adapter => "mysql",
  :database => "database_name",
  :username => "root",
  :password => "",
  :host => "localhost"
)

class Event < ActiveRecord::Base; end
class Person < ActiveRecord::Base; end

File.open("events.json", "w") { |f| f.write Event.all.to_json }
File.open("people.json", "w") { |f| f.write Person.all.to_json }

Вы также можете добавлять методы к классам ActiveRecord, если хотите сначала обрабатывать данные или включать или исключать определенные столбцы.

Person.all.to_json(:only => [ :id, :name ])

С помощью ActiveRecord вы не ограничены JSON. Вы также можете легко экспортировать XML или YAML

Person.all.to_xml
Person.all.to_yaml

Вы не ограничены MySQL. Любая база данных, поддерживаемая ActiveRecord (Postgres, SQLite3, Oracle... и т.д.).

И стоит упомянуть, что вы можете открыть другой дескриптор базы данных

require 'active_record'

ActiveRecord::Base.configurations["mysql"] = {
  :adapter  => 'mysql',
  :database => 'database_name',
  :username => 'root',
  :password => '',
  :host     => 'localhost'
}


ActiveRecord::Base.configurations["sqlite3"] = {
  :adapter  => 'sqlite3',
  :database => 'db/development.sqlite3'
}

class PersonMySQL < ActiveRecord::Base
  establish_connection "mysql"
end

class PersonSQLite < ActiveRecord::Base
  establish_connection "sqlite3"
end


PersonMySQL.all.each do |person|
    PersonSQLite.create(person.attributes.except("id"))
end

Вот короткое сообщение в блоге об этом http://www.seanbehan.com/how-to-export-a-mysql-database-to-json-csv-and-xml-with-ruby-and-the-activerecord-gem

Ответ 7

Я знаю, что это старо, но ради кого-то ищущего ответ...

Здесь есть библиотека JSON для MYSQL, которая может быть найдена здесь. Вам необходим root-доступ к вашему серверу и удобная установка плагинов (это просто).

1) загрузите lib_mysqludf_json.so в каталог плагинов вашей установки mysql

2) запустите файл lib_mysqludf_json.sql(это в значительной степени делает всю работу за вас. Если вы столкнулись с проблемой, просто удалите все, что начинается с "DROP FUNCTION..." )

3) закодируйте свой запрос примерно так:

SELECT json_array(
         group_concat(json_object( name, email))
FROM ....
WHERE ...

и он вернет что-то вроде

[ 
   { 
     "name": "something",
     "email": "[email protected]"
    }, 
   { 
     "name": "someone",
     "email": "[email protected]"
    }

]

Ответ 8

как описано в ссылке, он возвращает (как я упоминал) 15 результатов. (fwiw, я проверил эти результаты против 4000, которые я должен получить, и эти 15 совпадают с первыми 15 из 4000)

Это потому, что mysql ограничивает длину данных, возвращаемых группой concat, значению, установленному в @@group_concat_max_len, как только он достигает этой суммы, он усекает и возвращает то, что получил до сих пор.

Вы можете установить @@group_concat_max_len несколькими способами. reference Документация mysql...

Ответ 9

Вы можете экспортировать любой SQL-запрос в JSON непосредственно из PHPMyAdmin

Ответ 10

Кроме того, если вы экспортируете на прикладном уровне, не забудьте ограничить результаты. Например, если у вас есть 10M строк, вы должны получить часть результатов по частям.

Ответ 11

Используйте следующий код ruby ​​

require 'mysql2'

client = Mysql2::Client.new(
  :host => 'your_host', `enter code here`
  :database => 'your_database',
  :username => 'your_username', 
  :password => 'your_password')
table_sql = "show tables"
tables = client.query(table_sql, :as => :array)

open('_output.json', 'a') { |f|       
    tables.each do |table|
        sql = "select * from `#{table.first}`"
        res = client.query(sql, :as => :json)
        f.puts res.to_a.join(",") + "\n"
    end
}

Ответ 12

Для тех, кто хочет сделать это с помощью Python, и иметь возможность экспортировать все таблицы без предварительного определения имен полей и т.д., я написал короткий script для этого на следующий день, надеюсь, что кто-то сочтет это полезным:

from contextlib import closing
from datetime import datetime
import json
import MySQLdb
DB_NAME = 'x'
DB_USER = 'y'
DB_PASS = 'z'

def get_tables(cursor):
    cursor.execute('SHOW tables')
    return [r[0] for r in cursor.fetchall()] 

def get_rows_as_dicts(cursor, table):
    cursor.execute('select * from {}'.format(table))
    columns = [d[0] for d in cursor.description]
    return [dict(zip(columns, row)) for row in cursor.fetchall()]

def dump_date(thing):
    if isinstance(thing, datetime):
        return thing.isoformat()
    return str(thing)


with closing(MySQLdb.connect(user=DB_USER, passwd=DB_PASS, db=DB_NAME)) as conn, closing(conn.cursor()) as cursor:
    dump = {}
    for table in get_tables(cursor):
        dump[table] = get_rows_as_dicts(cursor, table)
    print(json.dumps(dump, default=dump_date, indent=2))

Ответ 13

Это может быть более нишевым ответом, но если вы находитесь в Windows и MYSQL Workbench, вы можете просто выбрать нужную таблицу и нажать "Экспорт/Импорт" в сетке результатов. Это даст вам несколько вариантов формата, в том числе .json

Ответ 14

Хорошо, выслушай меня, используй JavaScript...

Я знаю, что вы хотите вывести эти данные, но что вам действительно нужно, так это CSV → JSON-парсер/конвертер....

Итак, я написал вам один:

function str_fix(str) {
  var count = -1
  var new_str = ""
  while (str[++count])
    if (str[count] == ' ')
      new_str += '_'
  else
    new_str += str[count]
  return String(new_str)
}


function parseCSV(csv) {
  var topline = ""
  var data = []
  var count = -1
  let length = csv.length

  while (csv[++count] != '\n') {
    topline += csv[count]
  }

  topline = topline.split(',')
  var items = topline.length

  while (count + 1 < length) {
    var current_str = ""
    var current_count = items
    var values = {}
    while (count + 1 < length && csv[++count] != '\n') {
      current_str += csv[count]
    }
    current_str = current_str.split(',')

    while (current_count--)
      values[str_fix(topline[current_count])] = current_str[current_count]
    data.push(values)
  }
  return data
}

Используйте скрипт оболочки - запустите на cron или добавьте в systemd - этот mysqldumps в CSV и просто постобработайте CSV!

JSON это просто формат: D

Я знаю, год сердце говорит записать эти данные на диск, но вы уже сделали - как CSV (mysqldump).

Это решение может не подходить для вашего случая использования, но часто я вижу людей, которые интенсивно обрабатывают данные на диск и с диска, просто чтобы отобразить список десяти самых последних пользователей на панели инструментов, которые просматривают 4 или 5 раз в год - так что это может быть хорошим минималистским подходом для таких ситуаций, вместо того, чтобы конвертировать каждую унцию SQL, которую создает ваша БД, и хранить JSON на зиму...

Вот пример использования FancyGrid для упорядочивания данных: https://jsfiddle.net/mhouser_nowmediagroup/ksg35znv/

Вот для чего:

fetch('https://mjhd.me/zip_ranges.csv')
    .then(function(response) {
      return response.text()
    })
    .then(function(csv) {
      data = parseCSV(csv)
      outputTable(data)
    })

ПРОТИВ РАЗДЕЛА. Скрипт в скрипте удаляет пустые значения (и, следовательно, пустые столбцы), поэтому используйте приведенный выше для непознаваемых данных, которые могут содержать пустые значения...