基本上,我有一个现有的数据库,其中包含我使用继承 Base 的 SQLAlchemy ORM 创建的固定数量的表以及来自我创建的“CustomColumn”类的列对象列表。
我正在尝试使用某些日志文件中找到的值来填充我的数据库。问题是每隔一段时间就会在日志文件中引入新的键和值。显而易见的解决方案是手动将该键作为一列添加到表中,但我希望将整个过程自动化。
当我的 python 代码运行/更新数据库时,是否可以向表中添加一个新列,并使添加的列成为 sqlite 表和该表的 SQLAlchemy 元数据的永久功能?
这是我尝试提炼出的我认为相关的内容:
from sqlalchemy import ForeignKey, Column, String, Integer, SmallInteger, func, Sequence, DateTime
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.orm import relationship
Base = declarative_base()
...
# Do a bunch of session.add() for groups of keys:values found in log file
...
# Found a group with a key not in Base.metadata.tables[table_name].columns.keys()
#get rid of any added entries from this log file
session_savepoint.rollback()
# Create new CustomColumn instance
new_column = CustomColumn(new_column_name, new_column_type, classification = "FOO")
# Alter SQLite table
session.execute(f"ALTER TABLE {table_name} ADD {new_column_name} {new_column_type}")
# Add column to metadata
Base.metadata.tables[table_name].append_column(newColumn)
# Add instance of CustomColumn to the set of columns the table inherits
setattr(ColumnSet, new_column_name, new_column)
session.commit()
session.close()
# return a flag indicating this log file should be parsed again
任何关于我在这里出错的地方的指示将不胜感激,谢谢。
动态改变表结构以响应传入的数据是一种代码味道。相反,您应该设计表格,以便它们可以捕获值而无需更改其结构。
例如,如果您有一个 [log_entry] 表
[log_entry]
log_id logged_at device_id error_code
------ ------------------- --------- ----------
1 2023-11-25 09:39:43 device_1 error_1
然后您开始获取带有附加属性“self_repair”的日志条目,您可以更改表以添加新列,但更好的方法是将结构重构为父/子关系
[log_entry]
log_id logged_at
------ -------------------
1 2023-11-25 09:39:43
[log_item]
log_id type value
------ --------- --------
1 device_id device_1
1 error_code error_1
现在,当新的日志条目到达时,您只需添加它即可
[log_entry]
log_id logged_at
------ -------------------
1 2023-11-25 09:39:43
2 2023-11-25 09:51:23
[log_item]
log_id type value
------ --------- --------
1 device_id device_1
1 error_code error_1
2 device_id device_2
2 error_code error_2
2 self_repair Success
如果您需要呈现您的值作为单个“表”,您可以使用查询(或像pandas的
pivot()
这样的方法)来旋转它们:
log_id logged_at device_id error_code self_repair
------ ------------------- --------- ---------- -----------
1 2023-11-25 09:39:43 device_1 error_1
2 2023-11-25 09:51:23 device_2 error_2 Success
(透视结果有时称为“交叉表”。)