SqlAlchemy добавляет новое поле в класс и создает соответствующий столбец в таблице

Я хочу добавить поле в существующий сопоставленный класс, как бы я автоматически обновил таблицу sql. Предоставляет ли sqlalchemy метод обновления базы данных новым столбцом, если поле добавлено в класс.

4 Solutions collect form web for “SqlAlchemy добавляет новое поле в класс и создает соответствующий столбец в таблице”

Сама SQLAlchemy не поддерживает автоматическое обновление схемы, но есть сторонний инструмент SQLAlchemy Migrate для автоматизации миграции. Посмотрите, пожалуйста, главу «Рабочий процесс управления версиями схемы базы данных», чтобы узнать, как это работает.

Иногда Migrate работает слишком много – вы просто хотите, чтобы столбец автоматически добавлялся при запуске измененного кода. Итак, вот функция, которая делает это.

Предостережения: он зацикливается внутри внутренних компонентов SQLAlchemy и имеет тенденцию требовать небольших изменений каждый раз, когда SQLAlchemy подвергается серьезной ревизии. (Вероятно, есть намного лучший способ сделать это – я не эксперт по SQLAlchemy). Он также не обрабатывает ограничения.

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. Eg 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)) 
 # 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 – это последний пакет, который предлагает миграцию базы данных.

См. Документы sqlalchemy относительно миграции здесь .

  • Предложение VALUES в SQLAlchemy
  • Как исключить определенные поля для сериализации с помощью jsonpickle?
  • sqlalchemy существует для запроса
  • проблема при передаче данных с использованием объекта сеанса SQLAlchemy в цикле
  • Обновление таблицы из другой таблицы с несколькими столбцами в sqlalchemy
  • Время соединения Sql Alchemy Out
  • Postgresql - Вставить туда, где не существует, используя INSERT от sqlalchemy от SELECT
  • Flask-SQLAlchemy - модель не имеет атрибута 'foreign_keys'
  • SQLAlchemy - эквивалент INSERT или REPLACE
  • Может ли SQLAlchemy автоматически создавать отношения из схемы базы данных?
  • Почему Flask-migrate не может обновляться при столбце падения
  •  
    Interesting Posts for Van-Lav

    Предупреждение NameError для wireType в ABAQUS

    Получить нечетную длину палиндрома

    Можно ли использовать пользовательский ввод для регулярных выражений Python?

    Как получить завершение кода для программирования COM?

    Как использовать обрезанный путь для многоугольника Baseemap

    Как печатать данные с одинаковой ситуацией в отдельных погружениях через цикл for в шаблоне фляги

    с Python есть способ прослушать изменения, когда вставка или обновление производится в mongodb

    Использование Python и lxml для проверки XML на внешний DTD

    Должен ли я создавать объекты mapper или использовать декларативный синтаксис в SQLAlchemy?

    В чем разница между context_dict и контекстом в django, python?

    Есть ли переносимый дистрибутив Python 2.7 Windows без каких-либо библиотек?

    Как изменить атрибуты для всех объектов внутри списка в python (3)?

    Как я могу повысить эффективность этого цикла numpy

    использование pandas read_csv с отсутствующими данными

    Как получить доступ к данным, хранящимся в QModelIndex

    Python - лучший язык программирования в мире.