Tôi muốn thêm trường vào lớp được ánh xạ hiện có, làm cách nào để tự động cập nhật bảng sql. Có sqlalchemy cung cấp một phương pháp để cập nhật cơ sở dữ liệu với một cột mới, nếu một trường được thêm vào lớp.SqlAlchemy thêm Trường mới vào lớp và tạo cột tương ứng trong bảng
Trả lời
SQLAlchemy chính nó không hỗ trợ cập nhật tự động lược đồ, nhưng có một công cụ bên thứ ba SQLAlchemy Migrate để tự động di chuyển. Xem qua "Database schema versioning workflow" chapter để xem cách hoạt động.
Đôi khi Di chuyển quá nhiều công việc - bạn chỉ muốn cột tự động được thêm khi bạn chạy mã đã thay đổi. Vì vậy, đây là một chức năng mà làm điều đó.
Hãy cẩn thận: nó chọc xung quanh trong nội bộ SQLAlchemy và có xu hướng yêu cầu thay đổi nhỏ mỗi khi SQLAlchemy trải qua một phiên bản chính. (Có lẽ có một cách tốt hơn để làm điều này - tôi không phải là một chuyên gia về SQLAlchemy). Nó cũng không xử lý các ràng buộc.
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))
Cảm ơn bạn rất nhiều! Chính xác những gì tôi đang tìm kiếm. – 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à gói mới nhất mà cung cấp di cư của cơ sở dữ liệu.
- 1. thêm cột vào SQLAlchemy Bảng
- 2. Thêm cột mới vào bảng mysql lớn
- 3. Cách thêm cột mới vào bảng MYSQL
- 4. Thêm nút xóa vào cột trong bảng
- 5. Tạo lớp động trong SQLAlchemy
- 6. Django-tables2 - tự động thêm cột vào bảng - không thêm attrs vào thẻ bảng trong html
- 7. Thêm cột mới vào từng phần tử trong danh sách bảng hoặc khung dữ liệu
- 8. Thêm lớp CSS vào cột
- 9. jqGrid thêm cột mới
- 10. cách tự động tạo các cột SQLAlchemy
- 11. Thêm hàm tạo vào deftype tạo lớp
- 12. Thêm cột mới vào thẻ actions_as_taggable_on
- 13. Cách thêm bảng mới vào NOPCommerce v2.4
- 14. Cách thêm cột mới vào tệp CSV?
- 15. Bảng CDC không hoạt động sau khi thêm cột mới vào bảng nguồn
- 16. SQLAlchemy và các cột trống
- 17. Sqlite: thêm nhận xét vào bảng và cột?
- 18. "Thêm mới" vào trường khóa ngoài trong django modelform
- 19. jQueryMobile: làm mới sau khi tự động thêm hàng vào bảng có cột chuyển đổi
- 20. vấn đề thiết kế cơ sở dữ liệu khi thêm cột mới vào bảng từ ứng dụng
- 21. Thêm hàng và cột vào một bảng động với jQuery
- 22. Cách thêm cột nhận dạng mới vào bảng trong SQL Server?
- 23. cách thêm cột mới vào khóa chính composite hiện có
- 24. Symfony2 - FormBuilder - thêm một lớp vào trường và nhập
- 25. Nhanh chóng thêm bản sao của cột vào bảng MySQL
- 26. Thêm cột số nguyên vào bảng mysql hiện có dựa trên cột hiện có
- 27. Thêm các trường mới so với việc tạo bảng riêng biệt
- 28. Thêm các phương thức mới vào các lớp được tạo LINQ to SQL
- 29. Lập trình thêm hàng mới vào phân lớp QAbstractListModel
- 30. Thêm các trường tùy chỉnh vào bảng auth_user ở Django
xin cảm ơn, đã suy nghĩ nhiều ... – jagguli
Tôi có thể yêu cầu liên kết mới không? Cái đó dường như đã chết. Cảm ơn trước. – Nonsingular