anvil-works / anvil-runtime

The runtime engine for hosting Anvil web apps
https://anvil.works/open-source
Other
904 stars 117 forks source link

Incorrect database schema migration on 1.6.0 #45

Closed Akrog closed 3 years ago

Akrog commented 3 years ago

There seems to be a regression in 1.6.0 in the DB schema check to decide when a migration is necessary. This issue is not present in 1.5.5.

I run anvil-app-server version 1.6.0 on a container with a host directory volume for the database, and on first start it successfully creates the database and everything works, but if I kill the container and start it again it doesn't recognize the schema and suggests all kinds of crazy changes.

Pinning anvil-app-server to 1.5.5 on the pip installation in the Dockerfile and repeating the same procedure works fine.

Example of the suggested migration when there have been no changes to the DB schema in anvil.yaml:

Found 2 migration(s) for (base runtime) DB.                                                                                                                                                                                                                                                                                                                                                                                               
Executing Anvil migrations...                                                                                                                                                                                                                                                                                                                                                                                                             
Database currently at "2021-06-19-runtime-sessions"                                                                                                                                                                                                                                                                                                                                                                                       
0 migration(s) to perform.                                                                                                                                                                                                                                                                                                                                                                                                                
Database now at "2021-06-19-runtime-sessions"                                                                                                                                                                                                                                                                                                                                                                                             
Migration complete.                                                                                                                                                                                                                                                                                                                                                                                                                       
[TRACE anvil.app-server.run] Invalidating; new version 1                                                                                                                                                                                                                                                                                                                                                                                  
[INFO  anvil.app-server.tables] Data tables schema out of date. Here is the migration that will run if you restart Anvil with the --auto-migrate command-line flag:                                                                                                                                                                                                                                                                       
[INFO  anvil.app-server.tables] ({:type :UPDATE_TABLE, :table "providers", :title "Providers"}                                                                                                                                                                                                                                                                                                                                            
 {:type :DELETE_COLUMN, :table "providers", :column_name "name"}                                                                                                                                                                                                                                                                                                                                                                          
 {:type :DELETE_COLUMN, :table "providers", :column_name "image_link"}                                                                                                                                                                                                                                                                                                                                                                    
 {:type :DELETE_COLUMN, :table "providers", :column_name "driver_name"}                                                                                                                                                                                                                                                                                                                                                                   
 {:type :DELETE_COLUMN, :table "providers", :column_name "vat_id"}                                                                                                                                                                                                                                                                                                                                                                        
 {:type :DELETE_COLUMN, :table "providers", :column_name "address"}                                                                                                                                                                                                                                                                                                                                                                       
 {:type :DELETE_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                   
  :table "providers",                                                                                                                                                                                                                                                                                                                                                                                                                     
  :column_name "country_code"}                                                                                                                                                                                                                                                                                                                                                                                                            
 {:type :DELETE_COLUMN, :table "providers", :column_name "website"}                                                                                                                                                                                                                                                                                                                                                                       
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "providers",                                                                                                                                                                                                                                                                                                                                                                                                                     
  :column                                                                                                                                                                                                                                                                                                                                                                                                                                 
  {:name "user",                                                                                                                                                                                                                                                                                                                                                                                                                          
   :admin_ui {:width 200},                                                                                                                                                                                                                                                                                                                                                                                                                
   :type "link_single",                                                                                                                                                                                                                                                                                                                                                                                                                   
   :target "users"}}                                                                                                                                                                                                                                                                                                                                                                                                                      
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "providers",                                                                                                                                                                                                                                                                                                                                                                                                                     
  :column                                                                                                                                                                                                                                                                                                                                                                                                                                 
  {:name "display_name", :admin_ui {:width 200}, :type "string"}}                                                                                                                                                                                                                                                                                                                                                                         
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "providers",                                                                                                                                                                                                                                                                                                                                                                                                                     
  :column {:name "config", :admin_ui {:width 200}, :type "string"}}                                                                                                                                                                                                                                                                                                                                                                       
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "providers",                                                                                                                                                                                                                                                                                                                                                                                                                     
  :column {:name "created", :admin_ui {:width 200}, :type "datetime"}}                                                                                                                                                                                                                                                                                                                                                                    
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "providers",                                                                                                                                                                                                                                                                                                                                                                                                                     
  :column {:name "updated", :admin_ui {:width 200}, :type "datetime"}}                                                                                                                                                                                                                                                                                                                                                                    
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "providers",                                                                                                                                                                                                                                                                                                                                                                                                                     
  :column                                                                                                                                                                                                                                                                                                                                                                                                                                 
  {:name "provider_info",                                                                                                                                                                                                                                                                                                                                                                                                                 
   :admin_ui {:width 200},                                                                                                                                                                                                                                                                                                                                                                                                                
   :type "link_single",                                                                                                                                                                                                                                                                                                                                                                                                                   
   :target "providerinfo"}}                                                                                                                                                                                                                                                                                                                                                                                                               
 {:type :UPDATE_TABLE, :table "users", :title "Users"}                                                                                                                                                                                                                                                                                                                                                                                    
 {:type :DELETE_COLUMN, :table "users", :column_name "image_link"}                                                                                                                                                                                                                                                                                                                                                                        
 {:type :DELETE_COLUMN, :table "users", :column_name "driver_name"}                                                                                                                                                                                                                                                                                                                                                                       
 {:type :DELETE_COLUMN, :table "users", :column_name "vat_id"}                                                                                                                                                                                                                                                                                                                                                                            
 {:type :DELETE_COLUMN, :table "users", :column_name "address"}                                                                                                                                                                                                                                                                                                                                                                           
 {:type :DELETE_COLUMN, :table "users", :column_name "country_code"}                                                                                                                                                                                                                                                                                                                                                                      
 {:type :DELETE_COLUMN, :table "users", :column_name "website"}                                                                                                                                                                                                                                                                                                                                                                           
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "users",                                                                                                                                                                                                                                                                                                                                                                                                                         
  :column {:name "email", :admin_ui {:width 200}, :type "string"}}                                                                                                                                                                                                                                                                                                                                                                        
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "users",                                                                                                                                                                                                                                                                                                                                                                                                                         
  :column {:name "enabled", :admin_ui {:width 100}, :type "bool"}}                                                                                                                                                                                                                                                                                                                                                                        
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "users",                                                                                                                                                                                                                                                                                                                                                                                                                         
  :column                                                                                                                                                                                                                                                                                                                                                                                                                                 
  {:name "signed_up", :admin_ui {:width 200}, :type "datetime"}}                                                                                                                                                                                                                                                                                                                                                                          
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "users",                                                                                                                                                                                                                                                                                                                                                                                                                         
  :column                                                                                                                                                                                                                                                                                                                                                                                                                                 
  {:name "last_login", :admin_ui {:width 200}, :type "datetime"}}                                                                                                                                                                                                                                                                                                                                                                         
 {:type :ADD_COLUMN,                                                                                                                                                                                                                                                                                                                                                                                                                      
  :table "users",                                                                                                                                                                                                                                                                                                                                                                                                                         
  :column                                                                                                                                                                                                                                                                                                                                                                                                                                 
  {:name "password_hash", :admin_ui {:width 200}, :type "string"}})                                                                                                                                                                                                                                                                                                                                                                       

[INFO  anvil.app-server.tables] Anvil will now exit. Run with --ignore-invalid-schema to startup anyway, or --auto-migrate to apply the changes above. 

Link to a forum post of another user experiencing the same issue when migrating to 1.6.0

Akrog commented 3 years ago

I created a reproducer and pushed to https://github.com/Akrog/anvil-issue-45.

DB schema:

db_schema:
- name: Providers
  id: 148532
  python_name: providers
  columns:
    63VfP1JrMt8=:
      name: created
      type: datetime
      admin_ui: {order: 3, width: 200}
    gOyvB6eoXgY=:
      name: users
      type: liveObject
      backend: anvil.tables.Row
      admin_ui: {order: 0, width: 200}
      table_id: 148527
    sFdXtPCzTdA=:
      name: display_name
      type: string
      admin_ui: {order: 1, width: 200}
    yfv+w5o2s+Y=:
      name: config
      type: string
      admin_ui: {order: 2, width: 200}
  access: {python_name: providers, app_id: RQPID2OHG4B46QLT, server: full, client: none,
    table_mapping_name: null, table_mapping_id: null, table_id: 148532}