2014-04-08 5 views
5

Mam tabelę mysql "myTable", do której odwołuje się myTable.id za pomocą klucza obcego w innej tabeli. Muszę skrócić "myTable". Zwykle z powłoką mysql zrobiłbym:Nodejs kontynuuje sposób obcięcia klucza obcego tabeli odniesienia

mysql> SET FOREIGN_KEY_CHECKS = 0; truncate table myTable; SET FOREIGN_KEY_CHECKS = 1; 

Czy jest jakiś sposób na zrobienie tego z sequelize?

Próbowałem wykonać

sequelize.query('SET FOREIGN_KEY_CHECKS = 0; truncate table myTable; SET FOREIGN_KEY_CHECKS = 1;')

ale mam błąd:

`Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'truncate table myTable; SET FOREIGN_KEY_CHECKS = 1' at line 1` 

Gdybym wykonać zapytania seryjnie, nie mogę obciąć tabelę:

ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint 

Odpowiedz

8

To się dzieje, ponieważ sequelize nie pozwoli ci wykonać mnożenia e zapytania z jednym połączeniem sequelize.query. Opisany scenariusz jest teraz obsługiwany tylko dla sequelize.sync({ force: true }), który usuwa wszystkie tabele i odtwarza je później. Metoda ta jest wewnętrznie za pomocą następującego kodu:

https://github.com/sequelize/sequelize/blob/a014bd8d172fb8fd9881cee866abfcab842c30fc/lib/query-interface.js#L227-228

To w zasadzie ładuje każdy stół i sprawdza, czy są klucze obce. W takim przypadku sequelize spowoduje ich upuszczenie przed drugą tabelą. Prawdopodobnie mógłbyś przyjąć tę logikę. Ponadto: Jeśli zdecydujesz się na implementację tych rzeczy, prawdopodobnie możesz otworzyć żądanie ściągnięcia na github. To by było ciężko. Inną opcją, która prawdopodobnie działa, jest następujący:

sequelize.transaction(function(t) { 
    var options = { raw: true, transaction: t } 

    sequelize 
    .query('SET FOREIGN_KEY_CHECKS = 0', null, options) 
    .then(function() { 
     return sequelize.query('truncate table myTable', null, options) 
    }) 
    .then(function() { 
     return sequelize.query('SET FOREIGN_KEY_CHECKS = 1', null, options) 
    }) 
    .then(function() { 
     return t.commit() 
    }) 
}).success(function() { 
    // go on here ... 
}) 

To działa, ponieważ transakcje są za pomocą dedykowanego połączenia, dzięki czemu można łatwo wykonywać polecenia w wierszu.

+0

Dziękuję, że rozwiązałeś mój problem. – Juanra

+0

Innymi słowy, musimy dbać o nasze FK sami, ponieważ Sequelize nie powiedzie się tak źle cały czas https://github.com/sequelize/sequelize/issues/6894 – Green

+0

Mam błąd: 'Błąd: Sequelize.query został refaktoryzowany, aby używać tylko parametrów "sql" i "opcji". Proszę przeczytać dziennik zmian o BC. –

3

Używam kolejnej wersji 3.5.1 i sdepolds solution już nie działa, ponieważ sekwencja zmian została zmieniona. Dostosowując jego rozwiązanie skutkowałoby:

sequelize.transaction(function(t) { 
    var options = { raw: true, transaction: t } 

    return sequelize 
    .query('SET FOREIGN_KEY_CHECKS = 0', options) 
    .then(function() { 
     return sequelize.query('truncate table myTable', options) 
    }) 
    .then(function() { 
     return sequelize.query('SET FOREIGN_KEY_CHECKS = 1', options) 
    }) 
}).then(function() { 
    // go on here ... 
}) 

Według Sequelise's documentation ostatnia obietnica w łańcuchu wyzwala popełnić transakcji. Również drugi parametr (zero) w odpowiedzi sdepolds nie jest już potrzebny. Co więcej, sequelize.query musi zostać zwrócony na zewnątrz.

+0

Mam błąd: 'Błąd: Sequelize.zapytanie zostało refaktoryzowane, aby używać tylko parametrów "sql" i "opcji". Proszę przeczytać dziennik zmian o BC. –

3

Używam sequelize 3.24.3 i można zrobić

MyTableModel.truncate({ cascade: true }); 

Oto dokumentacja opcji

Only used in conjunction with TRUNCATE. Truncates all tables that have foreign-key references to the named table, or to any tables added to the group due to CASCADE.

+2

Nie działa. 'SequelizeDatabaseError: ER_TRUNCATE_ILLEGAL_FK: Nie można obciąć tabeli wymienionej w ograniczeniu klucza obcego' – Green

+1

Czy używasz zgodnej wersji? – ThomasThiebaud

+1

Praca z 'sequelize':' 3.24.3', ograniczenia FK zostały skonfigurowane jako 'ON DELETE SET NULL'. – Dr1Ku

1

mam to patrząc na another questioncascade i pracował dla mnie na v4.13.2

MyTableModel.destroy({ truncate: { cascade: true } }); 
+0

pracował dla mnie z v4.35.0 –