Desidero aggiungere un campo a una classe mappata esistente, come aggiornerei la tabella sql automaticamente. Sqlalchemy fornisce un metodo per aggiornare il database con una nuova colonna, se un campo viene aggiunto alla classe.SqlAlchemy aggiunge un nuovo campo alla classe e crea una colonna corrispondente nella tabella
risposta
SQLAlchemy non supporta gli aggiornamenti automatici dello schema, ma esiste uno strumento di terze parti SQLAlchemy Migrate per automatizzare le migrazioni. Guarda però "Database schema versioning workflow" chapter per vedere come funziona.
A volte la migrazione è troppo lavoro: si desidera aggiungere automaticamente una colonna quando si esegue il codice modificato. Quindi ecco una funzione che lo fa.
Avvertenze: si agita all'interno degli interni di SQLAlchemy e tende a richiedere piccole modifiche ogni volta che SQLAlchemy subisce una revisione importante. (Probabilmente c'è un modo molto migliore per farlo: non sono un esperto di SQLAlchemy). Inoltre non gestisce i vincoli.
import logging
import re
import sqlalchemy
from sqlalchemy import MetaData, Table, exceptions
import sqlalchemy.engine.ddl
_new_sa_ddl = sqlalchemy.__version__.startswith('0.7')
def create_and_upgrade(engine, metadata):
"""For each table in metadata, if it is not in the database then create it.
If it is in the database then add any missing columns and warn about any columns
whose spec has changed"""
db_metadata = MetaData()
db_metadata.bind = engine
for model_table in metadata.sorted_tables:
try:
db_table = Table(model_table.name, db_metadata, autoload=True)
except exceptions.NoSuchTableError:
logging.info('Creating table %s' % model_table.name)
model_table.create(bind=engine)
else:
if _new_sa_ddl:
ddl_c = engine.dialect.ddl_compiler(engine.dialect, None)
else:
# 0.6
ddl_c = engine.dialect.ddl_compiler(engine.dialect, db_table)
# else:
# 0.5
# ddl_c = engine.dialect.schemagenerator(engine.dialect, engine.contextual_connect())
logging.debug('Table %s already exists. Checking for missing columns' % model_table.name)
model_columns = _column_names(model_table)
db_columns = _column_names(db_table)
to_create = model_columns - db_columns
to_remove = db_columns - model_columns
to_check = db_columns.intersection(model_columns)
for c in to_create:
model_column = getattr(model_table.c, c)
logging.info('Adding column %s.%s' % (model_table.name, model_column.name))
assert not model_column.constraints, \
'Arrrgh! I cannot automatically add columns with constraints to the database'\
'Please consider fixing me if you care!'
model_col_spec = ddl_c.get_column_specification(model_column)
sql = 'ALTER TABLE %s ADD %s' % (model_table.name, model_col_spec)
engine.execute(sql)
# It's difficult to reliably determine if the model has changed
# a column definition. E.g. the default precision of columns
# is None, which means the database decides. Therefore when I look at the model
# it may give the SQL for the column as INTEGER but when I look at the database
# I have a definite precision, therefore the returned type is INTEGER(11)
for c in to_check:
model_column = model_table.c[c]
db_column = db_table.c[c]
x = model_column == db_column
logging.debug('Checking column %s.%s' % (model_table.name, model_column.name))
model_col_spec = ddl_c.get_column_specification(model_column)
db_col_spec = ddl_c.get_column_specification(db_column)
model_col_spec = re.sub('[(][\d ,]+[)]', '', model_col_spec)
db_col_spec = re.sub('[(][\d ,]+[)]', '', db_col_spec)
db_col_spec = db_col_spec.replace('DECIMAL', 'NUMERIC')
db_col_spec = db_col_spec.replace('TINYINT', 'BOOL')
if model_col_spec != db_col_spec:
logging.warning('Column %s.%s has specification %r in the model but %r in the database' %
(model_table.name, model_column.name, model_col_spec, db_col_spec))
if model_column.constraints or db_column.constraints:
# TODO, check constraints
logging.debug('Column constraints not checked. I am too dumb')
for c in to_remove:
model_column = getattr(db_table.c, c)
logging.warning('Column %s.%s in the database is not in the model' % (model_table.name, model_column.name))
def _column_names(table):
# Autoloaded columns return unicode column names - make sure we treat all are equal
return set((unicode(i.name) for i in table.c))
Grazie mille! Esattamente quello che stavo cercando. – kay
# database.py has definition for engine.
# from sqlalchemy import create_engine
# engine = create_engine('mysql://......', convert_unicode=True)
from database import engine
from sqlalchemy import DDL
add_column = DDL('ALTER TABLE USERS ADD COLUMN city VARCHAR(60) AFTER email')
engine.execute(add_column)
Alembic è l'ultimo pacchetto che offre la migrazione di database.
- 1. Come si aggiunge una colonna alla tabella sql server grande
- 2. aggiungi colonna a SQLAlchemy Tabella
- 3. Simple_form aggiunge classe alla forma
- 4. Come si aggiunge una colonna calcolata a una tabella?
- 5. SQLAlchemy - lunghezza massima della colonna
- 6. Globalmente si aggiunge alla riga con termine corrispondente in vim
- 7. Serve l'immagine memorizzata nella colonna SQLAlchemy LargeBinary
- 8. Crea un trigger che inserisce valori in una nuova tabella quando una colonna viene aggiornata
- 9. Ordine sqlalchemy per colonna calcolata
- 10. Sostituire/eliminare campo utilizzando sqlalchemy
- 11. GWT.create() crea sempre un nuovo oggetto nella memoria del browser?
- 12. In sqlite Come aggiungere una colonna nella tabella se la stessa colonna non esiste nella tabella
- 13. SQLAlchemy: proprietà personalizzata della query basata sul campo della tabella
- 14. Flask-SQLAlchemy controlla se esiste una riga nella tabella
- 15. Crea nuovo Dataframe con valori di campo vuoto/nullo
- 16. Come creare un nuovo database usando SQLAlchemy?
- 17. La migrazione di Laravel aggiunge il campo dopo che i dati sono nella tabella?
- 18. Costruttore corrispondente alla controparte nella definizione di tipo generico
- 19. Crea nuovo ClassLoader per ricaricare Classe
- 20. alcuna funzione corrispondente nella classe template
- 21. copiare un campo di tavolo in un altro campo nella stessa tabella
- 22. Aggiungi classe con jQuery per nella seconda colonna della tabella
- 23. Trova il valore massimo e mostra il valore corrispondente da un campo diverso nel server SQL
- 24. Inserire MySQL valore colonna timestamp con SQLAlchemy
- 25. Come posso ottenere la colonna della tabella corrispondente (td) dall'intestazione di una tabella (th)?
- 26. SqlAlchemy: crea l'oggetto se non esiste già?
- 27. Crea una tabella PDF
- 28. Targeting per colonna specifica nella tabella
- 29. SQLAlchemy: la colonna con ForeignKey crea automaticamente l'indice?
- 30. SQLAlchemy: verificare se l'oggetto è già presente nella tabella
ehi grazie, pensato tanto ... – jagguli
Posso chiedere un nuovo link? Quello sembra essere morto. Grazie in anticipo. – Nonsingular