我想将字段添加到现有映射类,我将如何自动更新sql表。如果将字段添加到类中,sqlalchemy是否提供了使用新列更新数据库的方法。SqlAlchemy将新字段添加到类中并在表中创建对应的列
11
A
回答
5
SQLAlchemy本身不支持模式的自动更新,但有第三方工具来自动化迁移。看看"Database schema versioning workflow" chapter看看它是如何工作的。
9
有时迁移工作太多 - 您只需要在运行更改后的代码时自动添加列。所以这里有一个功能。注意事项:它在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. 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))
+0
非常感谢!正是我在找什么。 – kay 2012-12-18 11:46:05
0
# 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)
0
Alembic是提供数据库的迁移最新的软件包。
相关问题
- 1. 动态创建对象并将其添加到列表中JavaFX
- 2. Hibernate XML映射 - 创建新字段并将其添加到多列约束中
- 3. 将列添加到SQLAlchemy表
- 4. 在列表中添加数字并追加到新列表中
- 5. MySQL的 - 列添加到表或创建新表并加入
- 6. 将新属性添加到列表中的对象并返回新列表
- 7. Sharepoint - 将字段添加到内容类型不更新列表
- 8. 从现有表插入到新表中并添加新字段
- 9. 使用Enumerable.Where的结果创建对象并将它们添加到列表中
- 10. 如何将在models.py中创建的新类添加到admin.py(django)
- 11. 在循环中创建对象的新实例以添加到列表中
- 12. 通过按键创建新对象并将其添加到列表
- 13. 如何使用javascript创建新列表并将列表项添加到新列表中
- 14. 在PowerShell中将新创建的对象从一个列表添加到另一个列表中
- 15. 如何在“创建”中在sails.js/waterline中添加新字段?
- 16. web2py - 从表中创建下拉字段,但也添加新的记录到表
- 17. 将类的实例添加到不同类中的数组列表中,在创建实例时自动创建
- 18. 将字段添加到Spotify列表
- 19. 将字段添加到列表
- 20. 创建一个列表并将文件名添加到此列表中
- 21. 添加新列到数据库表中使用的SQLAlchemy,pyodbc
- 22. 从列表中创建复选框并添加到winform中
- 23. 将阵列列表中的对象添加到类的实例
- 24. 将列表中的类对象添加到QWidget中
- 25. 在domdocument中创建XML片段并添加到它的父代
- 26. 如何在CalEvent表中创建一个与Calendar portlet的“添加事件”页面中新创建的字段相对应的新列?
- 27. 创建UIview并将其添加到表中的单元格iphone
- 28. 如何创建(或添加)并将新布局填充到片段中
- 29. 添加并更新列/创建新表与附加行
- 30. 创建类型对象的通用列表并添加一个字符串
嘿谢谢,以为这么多... – jagguli 2010-01-21 13:12:46
我可以问一个新的链接吗?那个似乎已经死了。提前致谢。 – Nonsingular 2017-06-06 18:15:12