gpt4 book ai didi

python - sqlalchemy在postgres中使用继承

转载 作者:太空狗 更新时间:2023-10-30 00:18:11 25 4
gpt4 key购买 nike

在尝试学习 sqlalchemy(和 python)时,我试图复制一个已经存在的项目,但我无法弄清楚 sqlalchemy 和 postgres 的继承。

这是我们的 postgres 数据库的一个例子(显然,这是简化的):

CREATE TABLE system (system_id SERIAL PRIMARY KEY, 
system_name VARCHAR(24) NOT NULL);
CREATE TABLE file_entry(file_entry_id SERIAL,
file_entry_msg VARCHAR(256) NOT NULL,
file_entry_system_name VARCHAR(24) REFERENCES system(system_name) NOT NULL);
CREATE TABLE ops_file_entry(CONSTRAINT ops_file_entry_id_pkey PRIMARY KEY (file_entry_id),
CONSTRAINT ops_system_name_check CHECK ((file_entry_system_name = 'ops'::bpchar))) INHERITS (file_entry);
CREATE TABLE eng_file_entry(CONSTRAINT eng_file_entry_id_pkey PRIMARY KEY (file_entry_id),
CONSTRAINT eng_system_name_check CHECK ((file_entry_system_name = 'eng'::bpchar)) INHERITS (file_entry);
CREATE INDEX ops_file_entry_index ON ops_file_entry USING btree (file_entry_system_id);
CREATE INDEX eng_file_entry_index ON eng_file_entry USING btree (file_entry_system_id);

然后插入将通过触发器完成,以便将它们正确插入到子数据库中。像这样的东西:

CREATE FUNCTION file_entry_insert_trigger() RETURNS "trigger"
AS $$
DECLARE
BEGIN
IF NEW.file_entry_system_name = 'eng' THEN
INSERT INTO eng_file_entry(file_entry_id, file_entry_msg, file_entry_type, file_entry_system_name) VALUES (NEW.file_entry_id, NEW.file_entry_msg, NEW.file_entry_type, NEW.file_entry_system_name);
ELSEIF NEW.file_entry_system_name = 'ops' THEN
INSERT INTO ops_file_entry(file_entry_id, file_entry_msg, file_entry_type, file_entry_system_name) VALUES (NEW.file_entry_id, NEW.file_entry_msg, NEW.file_entry_type, NEW.file_entry_system_name);
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

总而言之,我有一个父表,其中包含另一个表的外键。然后我有 2 个子表,插入是根据给定值完成的。在我上面的示例中,如果 file_entry_system_name 是“ops”,则该行进入 ops_file_entry 表; 'eng' 进入 eng_file_entry_table。我们的生产环境中有数百个子表,考虑到数据量,它确实加快了处理速度,所以我想保持相同的结构。我可以查询父表,只要我给它正确的“system_name”,它就会立即知道要查看哪个子表。

我的愿望是用 sqlalchemy 来模拟它,但我找不到任何详细说明的示例。我通过示例查看了 sqlalchemy 生成的 sql,我可以看出它在数据库端没有做任何类似的事情。

我能想到的最好的是:

class System(_Base):
__tablename__ = 'system'
system_id = Column(Integer, Sequence('system_id_seq'), primary_key = True)
system_name = Column(String(24), nullable=False)
def __init(self, name)
self.system_name = name
class FileEntry(_Base):
__tablename__ = 'file_entry'
file_entry_id = Column(Integer, Sequence('file_entry_id_seq'), primary_key=True)
file_entry_msg = Column(String(256), nullable=False)
file_entry_system_name = Column(String(24), nullable=False, ForeignKey('system.system_name'))
__mapper_args__ = {'polymorphic_on': file_entry_system_name}
def __init__(self, msg, name)
self.file_entry_msg = msg
self.file_entry_system_name = name
class ops_file_entry(FileEntry):
__tablename__ = 'ops_file_entry'
ops_file_entry_id = Column(None, ForeignKey('file_entry.file_entry_id'), primary_key=True)
__mapper_args__ = {'polymorphic_identity': 'ops_file_entry'}

最后,我错过了什么?我如何告诉 sqlalchemy 将插入到 FileEntry 中的任何内容与系统名称“ops”相关联以转到“ops_file_entry”表?我的理解有问题吗?

对我应该做什么有一些洞察力会很棒。

最佳答案

您只需创建一个新的 ops_file_entry 实例(这不应该是 OpsFileEntry 吗?),将其添加到 session 中,刷新后,将插入一行进入表 file_entry 以及表 ops_file_entry

您不需要设置 file_entry_system_name 属性,也不需要设置触发器。

关于python - sqlalchemy在postgres中使用继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6782592/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com