Таблица SQLite со слиянием Git - PullRequest
6 голосов
/ 15 февраля 2009

У меня есть файл журнала, хранящийся в базе данных SQLite, который я хотел бы распространить в репозитории git.

Позже я бы хотел, чтобы изменения в файле журнала автоматически сливались с оригиналом.

Это сработает? Будет ли автоматическое слияние двоичных файлов в файл SQLite чаще, чем нет?

Ответы [ 6 ]

17 голосов
/ 05 августа 2010

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

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

В вашем .git / config:

[merge "sqlite3"]
    name = sqlite3 merge driver
    driver = merge-sqlite3 %O %A %B

[diff "sqlite3"]   
    name = sqlite3 diff driver  
    command = diff-sqlite3 

в .gitattributes:

signons.sqlite diff=sqlite3 merge=sqlite3

И где-то на вашем пути, с именем diff-sqlite3

#!/usr/bin/perl -w

use File::Temp  qw/ :POSIX /;
use IPC::Run qw/run/ ;

@ARGV == 7 or die sprintf 'wtf %s', join(' ', @ARGV);

my ($name, $x, $y) = ($ARGV[0], $ARGV[1], $ARGV[4]);

my ($a, $b);

eval { 
  $a = tmpnam();
  $b = tmpnam();

  run ['sqlite3', $x, '.dump'], '>', $a or die 'sqlite3 failed';
  run ['sqlite3', $y, '.dump'], '>', $b or die 'sqlite3 failed';

  print "diff-sqlite3 a/$name b/$name\n";
  run ['diff', '-u', $a, $b, '--label', "a/$name", '--label', "b/$name"], '>', \*STDOUT;   

  unlink $a;
  unlink $b; 
  1;
} or do {
  unlink $a if defined $a;
  unlink $b if defined $b;
  die $@; 
}

также на вашем пути, с именем merge-sqlite3

#!/usr/bin/perl -w

use File::Temp  qw/ :POSIX /;
use IPC::Run qw/run/ ;

@ARGV == 3 or die sprintf 'wtf %s', join(' ', @ARGV);

my ($o, $a, $b) = @ARGV; 

print "MERGEING SQLITE FILES $o $a $b\n"; 


eval { 
  $ad = tmpnam();
  $bd = tmpnam();
  $od = tmpnam(); 

  run ['sqlite3', $o, '.dump'], '>', $od or die 'sqlite3 failed';
  run ['sqlite3', $a, '.dump'], '>', $ad or die 'sqlite3 failed';
  run ['sqlite3', $b, '.dump'], '>', $bd or die 'sqlite3 failed';

  run ['merge', $ad, $od, $bd] or do {
    my $newname = "$a.dump";
    my $n = 0;
    while (-e $newname) {
      ++$n;
      $newname = "$a.dump.$n";
    }
    print "merge failed, saving dump in $newname\n";
    rename $ad, $newname;
    undef $ad; 
    die 'merge failed';
  };

  unlink $a or die $!;
  my $err; 
  run ['sqlite3', $a], '>', \*STDOUT, '2>', \$err, '<', $ad;
  if ('' ne $err) {
    print STDERR $err;
    die 'sqlite3 failed';
  }  

  unlink $ad if defined $ad;
  unlink $bd; 
  unlink $od;
  1;
} or do {
  unlink $ad if defined $ad;
  unlink $bd if defined $bd;
  unlink $od if defined $od;

  die $@; 
}

Я только что взломал их прямо сейчас, так что теперь вам, возможно, придется сгладить изломы.

см .: http://git -scm.com / docs / gitattributes и http://git -scm.com / docs / git-config

6 голосов
/ 15 февраля 2009

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

Единственное автоматическое объединение, которое попытается выполнить git, - это объединение текстовых файлов. Файл журнала (обычно) представляет собой текстовый файл, так почему бы не поместить его непосредственно в git, а не в базу данных?

5 голосов
/ 15 февраля 2009

Я сомневаюсь, что любая общая система контроля версий (git, svn, cvs и т. Д.) Может обрабатывать базу данных описанными вами способами. Если вы настаиваете на использовании git для слияния баз данных, лучше всего конвертировать базу данных в текстовый файл, объединять текстовый файл и заново создавать базу данных. Например,

sqlite3 .dump > dump_file.txt

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

sqlite3 newdatabase.db < modified_dump_file.txt

Вы должны быть в состоянии автоматизировать это с помощью какого-то git-хука (я не слишком знаком с git).

2 голосов
/ 09 июля 2017

Несмотря на то, что этот вопрос задавался 8+ лет назад, я выпустил инструмент, который делает именно то, что вы просите. Он использует собственный драйвер diff, использующий инструмент sqlite projects 'sqldiff', UUID в качестве первичных ключей и исключает rowl rowid. Это все еще в альфа-версии, поэтому обратная связь приветствуется.

https://github.com/cannadayr/git-sqlite

1 голос
/ 07 сентября 2011

Я переопределил драйвер diff выше в сценарии оболочки и обнаружил, что он не работает должным образом во всех случаях. Сценарий предполагает, что первые два параметра дают файлы для сравнения, но согласно man git параметры, заданные сценарию:

путь старый файл старый шестнадцатеричный старый режим новый файл новый шестнадцатеричный новый режим

Вот разница, которая сделала это для меня:

#!/bin/sh

FILE_PATH=$1
OLD_FILE=$2
OLD_HEX=$3
OLD_MODE=$4
NEW_FILE=$5
NEW_HEX=$6
NEW_MODE=$7

A=`tempfile`
B=`tempfile`
test -f ${A} && test -f ${B} || exit 1

sqlite3 ${OLD_FILE} .dump > ${A} &&
sqlite3 ${NEW_FILE} .dump > ${B} &&
diff -u ${A} ${B} --label "${FILE_PATH}@${OLD_HEX}" --label "${FILE_PATH}@${NEW_HEX}"

rm ${A}
rm ${B}
1 голос
/ 15 февраля 2009

В общем случае нет способа правильно объединить двоичные файлы, поэтому git не может и не будет этого делать.

С некоторыми усилиями вы можете использовать git для создания версии дампов базы данных, но, за исключением очень простых случаев, вам придется делать больше, чем просто использовать прямые дампы. Вам нужно подумать о том, как отсортированные строки сортируются на основе ваших ключевых столбцов, как минимум. В противном случае вы получите ложные конфликты или слияния, которые создают синтаксически допустимые дампы, представляющие базу данных мусора.

F.ex., Если разные версии строки с одним и тем же ключом появляются в разных строковых областях разных версий дампа, git может посчитать разумным оставить их обе. Результирующий дамп будет иметь два представления одной и той же строки, что является бессмысленным.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...