J'ai compris cette erreur dans le sens que "les données de caractères qui peuvent être stockées dans Mysql2 font jusqu'à 767 octets! Elles ne peuvent pas être migrées vers Mysql telles quelles!".
Sur la base de cette erreur, dans cet article, j'ai pratiqué les deux méthodes suivantes.
La chose la plus importante en plus est l'utilisation de MySQL. Cela signifie "si vous pouvez ou non utiliser des pictogrammes est décidé lors de la définition des exigences."
Entrons dans les détails! !! !!
L'erreur «Mysql2 :: Error: la clé spécifiée était trop longue; la longueur maximale de la clé est de 767 octets» s'est produite.
【Terminal】
〇〇@〇〇noMacBook-Air devise_app % rails db:migrate:reset
Dropped database 'devise_app_development'
Dropped database 'devise_app_test'
Created database 'devise_app_development'
Created database 'devise_app_test'
== 20200925212154 DeviseCreateUsers: migrating ================================
-- create_table(:users)
-> 0.0174s
-- add_index(:users, :email, {:unique=>true})
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Specified key was too long; max key length is 767 bytes
/Users/〇〇/projects/devise_app/db/migrate/20200925212154_devise_create_users.rb:39:in `change'
/Users/〇〇/projects/devise_app/bin/rails:9:in `<top (required)>'
/Users/〇〇/projects/devise_app/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Specified key was too long; max key length is 767 bytes
/Users/〇〇/projects/devise_app/db/migrate/20200925212154_devise_create_users.rb:39:in `change'
/Users/〇〇/projects/devise_app/bin/rails:9:in `<top (required)>'
/Users/〇〇/projects/devise_app/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Caused by:
Mysql2::Error: Specified key was too long; max key length is 767 bytes
/Users/〇〇/projects/devise_app/db/migrate/20200925212154_devise_create_users.rb:39:in `change'
/Users/〇〇/projects/devise_app/bin/rails:9:in `<top (required)>'
/Users/〇〇/projects/devise_app/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:migrate:reset => db:migrate
(See full trace by running task with --trace)
--Utilisation de Rails 6.0.0 --Mysql2 est utilisé pour la base de données (l'application est Sequel Pro) --Utilisez une gemme appelée devise (le modèle a donc été créé avec des rails g devise user) --Dans la conception, j'essayais de créer une colonne de type string (exemple: t.string: email) dans le fichier de migration. --Lorsque j'ai créé un fichier de migration et exécuté rails db: migrate, une erreur s'est produite.
--Vérifier avec les rails db: migrer: état → Il est en panne
Je n'ai pas compris le concept et je l'ai compris comme suit.
――Le code de caractère est le code attribué au caractère, tel que le n ° 1 pour "A" et le n ° 2 pour "I". (En fait, cela semble être plus compliqué en utilisant des nombres de base, etc.)
―― «utf8» est le code de caractère le plus populaire au monde. "Utf8" exprime des caractères de 1 à 4 octets, mais MySQL ne peut gérer que 3 octets.
"Utf8mb4" est un code de caractère à manipuler dans la base de données MySQL. Dans Mysql, les pictogrammes correspondent à 4 octets de "utf8", donc les pictogrammes ne peuvent être manipulés qu'avec "utf8mb4".
Dans MySQL, vous pouvez enregistrer jusqu'à "255 caractères".
En d'autres termes, dans MySQL
--utf8 est le code de caractère qui gère les caractères, et utf8bm4 est le code de caractère qui gère les pictogrammes.
Le nombre de caractères pouvant être
Puisque "utf8" utilise "3 octets", "767 octets ➗ 3 octets = jusqu'à 255 caractères"
Puisque "utf8mb4" utilise "4 octets", "767 octets ➗ 4 octets = jusqu'à 191 caractères"
La valeur par défaut de la chaîne étant de 255 caractères
"3 octets ❌ 255 caractères = 765 octets" (utf8)
"4 octets ❌ 255 caractères = 1020 octets" (utf8bm4): point_right_tone3: Il dépasse 767 octets qui peuvent être sauvés par MySQL! !! : point_right_tone3: Cette fois je suis dans cet état et c'est une erreur
Je comprends que.
Maintenant que la cause de l'erreur a été élucidée, il est important de la résoudre.
Comme je l'ai mentionné au début,
Tout d'abord, je l'ai résolu par la méthode ci-dessus! !! !! (Merci)
Si vous donnez un aperçu de la solution,
【problème】 "4 octets ❌ 255 caractères = 1020 octets" (utf8bm4): point_right_tone3: Il dépasse 767 octets qui peuvent être sauvés par MySQL! !! : point_right_tone3: Cette fois je suis dans cet état et c'est une erreur
[Y penser] Ensuite, fixons la limite supérieure du nombre de caractères à 191 caractères pour qu'elle ne dépasse pas 767 octets ("4 octets ❌ 191 caractères = 764 octets")! C'est une méthode. (Comment utiliser utf8bm4 tel quel pour que les pictogrammes puissent être utilisés)
Créez un nouveau mysql.rb comme indiqué ci-dessous sous config / initializer. (Y compris le code ci-dessous, il est tiré de l'article de @ terufumi1122.)
config/initializer/mysql.rb
require 'active_record/connection_adapters/abstract_mysql_adapter'
module ActiveRecord
module ConnectionAdapters
class AbstractMysqlAdapter
NATIVE_DATABASE_TYPES[:string] = { :name => "varchar", :limit => 191 }
end
end
end
Après avoir entré le fichier ci-dessus
【Terminal】
rails db:migrate
Quand je l'ai fait, il a été migré avec succès! !! !! (Quand j'ai regardé Sequel Pro, qui est MySQL, il y avait une colonne.)
Eh bien, je l'ai résolu en toute sécurité, mais j'ai pensé que je pourrais penser à la façon suivante de penser à la méthode qui ne dépasse pas 767 octets pour le problème.
【problème】 "4 octets ❌ 255 caractères = 1020 octets" (utf8bm4): point_right_tone3: Il dépasse 767 octets qui peuvent être sauvés par MySQL! !! : point_right_tone3: Cette fois je suis dans cet état et c'est une erreur
[Y penser] Ensuite, si vous n'utilisez pas de pictogrammes dans l'application, pourquoi ne pas le changer en "3 octets ❌ 255 caractères = 765 octets" (utf8)? En d'autres termes, au lieu de créer un fichier avec 191 caractères ou moins, le code de caractère décrit dans "config> database.yml" devrait être réécrit de "utf8bm4" à "utf8" et migré! ??
J'ai pensé.
Je vais pratiquer à partir d'ici, mais de la conclusion, j'ai appris que "il sera recréé à partir du modèle (il ne suffit pas de réécrire la migration)". (Autrement dit, c'est gênant et difficile.)
«Je ne peux pas réécrire la migration» signifie qu’un mystérieux fichier de migration (sans instruction) apparaît avec «rails db: migrate», et que ce fichier de migration n’est pas nécessaire, alors changez-le en fichier fictif et supprimez-le ou réinitialisez-le. Mais même si j'essaye de l'effacer, ça ne disparaît pas.
J'ai effacé le modèle avec "rails d conception user" et je l'ai recréé avec "rails g devise user", et j'ai finalement obtenu une application avec le code de caractère "utf8" sans aucune erreur.
〇〇@〇〇noMacBook-Air devise_app % rails db:rollback
== 20200925212154 DeviseCreateUsers: reverting ================================
-- remove_index(:users, {:column=>:reset_password_token})
-> 0.0099s
-- remove_index(:users, {:column=>:email})
-> 0.0074s
-- drop_table(:users)
-> 0.0040s
== 20200925212154 DeviseCreateUsers: reverted (0.0250s) =======================
〇〇@〇〇noMacBook-Air devise_app % rails db:migrate:status
database: devise_app_development
Status Migration ID Migration Name
--------------------------------------------------
down 20200925212154 Devise create users
〇〇@〇〇noMacBook-Air devise_app % rails db:migrate
== 20200925212154 DeviseCreateUsers: migrating ================================
-- create_table(:users)
rails aborted!
StandardError: An error has occurred, all later migrations canceled:
Mysql2::Error: Table 'users' already exists
/Users/〇〇/projects/devise_app/db/migrate/20200925212154_devise_create_users.rb:5:in `change'
/Users/〇〇/projects/devise_app/bin/rails:9:in `<top (required)>'
/Users/〇〇/projects/devise_app/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Caused by:
ActiveRecord::StatementInvalid: Mysql2::Error: Table 'users' already exists
/Users/〇〇/projects/devise_app/db/migrate/20200925212154_devise_create_users.rb:5:in `change'
/Users/〇〇/projects/devise_app/bin/rails:9:in `<top (required)>'
/Users/〇〇/projects/devise_app/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Caused by:
Mysql2::Error: Table 'users' already exists
/Users/〇〇/projects/devise_app/db/migrate/20200925212154_devise_create_users.rb:5:in `change'
/Users/〇〇/projects/devise_app/bin/rails:9:in `<top (required)>'
/Users/〇〇/projects/devise_app/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password:
socket: /tmp/mysql.sock
〇〇@〇〇noMacBook-Air devise_app % rails db:reset
Dropped database 'devise_app_development'
Dropped database 'devise_app_test'
Created database 'devise_app_development'
Created database 'devise_app_test'
You have 1 pending migration:
20200925212154 DeviseCreateUsers
Run `rails db:migrate` to update your database then try again.
〇〇@〇〇noMacBook-Air devise_app % rails db:migrate
== 20200925212154 DeviseCreateUsers: migrarails db:migrateting ================================
-- create_table(:users)
-> 0.0109s
-- add_index(:users, :email, {:unique=>true})
-> 0.0087s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.0085s
== 20200925212154 DeviseCreateUsers: migrated (0.0283s) =======================
〇〇@〇〇noMacBook-Air devise_app % rails db:migrate:status
database: devise_app_development
Status Migration ID Migration Name
--------------------------------------------------
up 000 ********** NO FILE **********
up 20200925212154 Devise create users
〇〇@〇〇noMacBook-Air devise_app % rails db:rollback STEP=2
〇〇@〇〇noMacBook-Air devise_app %
〇〇@〇〇noMacBook-Air devise_app % rails db:migrate:status
database: devise_app_development
Status Migration ID Migration Name
--------------------------------------------------
up 000 Sample
down 20200925212154 Devise create users
〇〇@〇〇noMacBook-Air devise_app % rails db:reset
Dropped database 'devise_app_development'
Dropped database 'devise_app_test'
Created database 'devise_app_development'
Created database 'devise_app_test'
You have 1 pending migration:
20200925212154 DeviseCreateUsers
Run `rails db:migrate` to update your database then try again.
〇〇@〇〇noMacBook-Air devise_app % rails db:migrate:status
database: devise_app_development
Status Migration ID Migration Name
--------------------------------------------------
up 000 ********** NO FILE **********
down 20200925212154 Devise create users
〇〇noMacBook-Air devise_app % rails d devise user
Running via Spring preloader in process 10337
invoke active_record
remove db/migrate/20200925212154_devise_create_users.rb
remove app/models/user.rb
invoke test_unit
remove test/models/user_test.rb
remove test/fixtures/users.yml
route devise_for :users
〇〇noMacBook-Air devise_app % rails g devise user
Running via Spring preloader in process 10485
invoke active_record
create db/migrate/20200926073222_devise_create_users.rb
create app/models/user.rb
invoke test_unit
create test/models/user_test.rb
create test/fixtures/users.yml
insert app/models/user.rb
route devise_for :users
〇〇noMacBook-Air devise_app % rails db:migrate
== 20200926073222 DeviseCreateUsers: migrating ================================
-- create_table(:users)
-> 0.0275s
-- add_index(:users, :email, {:unique=>true})
-> 0.0434s
-- add_index(:users, :reset_password_token, {:unique=>true})
-> 0.0108s
== 20200926073222 DeviseCreateUsers: migrated (0.0821s) =======================
〇〇noMacBook-Air devise_app % rails db:migrate:status
database: devise_app_development
Status Migration ID Migration Name
--------------------------------------------------
up 20200926073222 Devise create users
c'est tout.
J'ai essayé de pratiquer la considération, Il s'avère que pour modifier les informations dans database.yml, vous devez remodeler le modèle au lieu d'utiliser un sac en rouleau.
Cette fois, je n'ai pas beaucoup écrit sur le modèle, donc ça ne m'a pas affecté, S'il s'agit de recréer la table, la colonne, l'enregistrement, la migration, etc. y compris le modèle, ce sera gênant et difficile.
J'ai appris qu'il est important de définir les exigences pour l'édition de database.yml, y compris utf8 (avant de faire "rails db: create" au début), puis de le définir.
Après cela, j'ai envisagé une méthode qui ne dépasse pas "767 octets" cette fois, mais l'article de @ terufumi1122 dit aussi qu'il est permis de dépasser "767 octets".
Afin de résoudre l'erreur, j'estime qu'il est nécessaire d'examiner la demande de manière flexible dans diverses directions selon le but, et que le point de vue «POURQUOI» est important pour augmenter le nombre de retraits.
Merci d'avoir regardé. Si vous connaissez la cause du fichier mystère ou si vous avez publié quelque chose de mal, veuillez me le faire savoir.
Recommended Posts