在运行时使用 SQLAlchemy(或不使用)将列添加到 SQLite 表

问题描述 投票:0回答:1

基本上,我有一个现有的数据库,其中包含我使用继承 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

任何关于我在这里出错的地方的指示将不胜感激,谢谢。

python sqlite sqlalchemy
1个回答
0
投票

动态改变表结构以响应传入的数据是一种代码味道。相反,您应该设计表格,以便它们可以捕获值而无需更改其结构。

例如,如果您有一个 [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    

(透视结果有时称为“交叉表”。)

© www.soinside.com 2019 - 2024. All rights reserved.