繁体   English   中英

如何使用 ORM 从 SqlAlchemy 的多值字段中获取对象列表?

[英]How to get list of objects from multi-value field with SqlAlchemy using ORM?

我有来自客户端的 MS Access DB 文件 (.accdb),需要使用 declarative_base class 描述表和列。 正如我在表构造函数中看到的 - 其中一个列具有 Integer 值,并且与另一个表中的另一列(外键)具有“一对多”关系。 但实际上在这个外键中存储的不是单个 Integer 值,而是带有用分号分隔的数值的字符串。 这种技术称为“多值字段”。 事实上,这是没有关联表的“多对多”关系。

非常简化的方案:

Persons
-------------
id - Integer
name - String
vacancy_id - Integer (multi-value, Foreign key of Vacancies.id)

Vacancies
-------------
id - Integer
vacancy_name - String

我尝试使用 declarative_base 父 class 将 map 类添加到表中。 但是在没有关联表的情况下找不到如何声明“多对多”关系。 现在我有这样的代码。

Base = declarative_base()


class Vacancy(Base):
    __tablename__ = 'Vacancies'
    id = sa.Column(sa.Integer, name='id', primary_key=True, autoincrement=True)
    vacancy_name = sa.Column(sa.String(255), name='vacancy_name')


class Person(Base):
    __tablename__ = 'Persons'
    id = sa.Column(sa.Integer, name='id', primary_key=True, autoincrement=True)
    name = sa.Column(sa.String(255), name='name')
    vacancy_id = sa.Column(sa.Integer, ForeignKey(Vacancy.id), name='vacancy_id')
    vacancies = relationship(Vacancy)

在请求人期间,我有奇怪的行为:

  • 如果未指定 vacancy_id,我将 Person.vacancies 设为 None。
  • 如果 vacancy_id 指定为单个值(即“1”),则在 Person.vacancies 中我得到单个 object 的空缺 class。
  • 如果 vacancy_id 指定为多个值(即“1;2;3”),在 Person.vacancies 我也得到无。

当然,我可以请求原始 Person.vacancy_id,用分号分隔,然后请求获取带有 ID 列表的空缺。

但我想知道 - 如果 SqlAlchemy 可以处理“多值字段”? 处理此类文件的最佳方式是什么?

更新目前我做了以下解决方法来自动解析多值列。 这应该添加到 Persons class:

@orm.reconstructor
def load_on_init(self):
    if self.vacancy_id:
        ids = self.vacancy_id.split(';')
        self.vacancies = [x for x in Vacancy.query.filter(Vacancy.id.in_(ids)).all()]
    else:
        self.vacancies = []

空缺 class 应具有以下属性:

query = DBSession.query_property()

最后,我们必须准备 session 以供课堂使用:

engine = create_engine(CONNECTION_URI)
DBSession = scoped_session(sessionmaker(bind=engine))
Base = declarative_base()

Access ODBC 对多值查找字段的支持非常有限。 此类字段实际上是使用隐藏关联表(名称类似于f_1BC9E55B5578456EB5ACABC99BB2FF0B_vacancies )实现的,但这些表无法从 SQL 语句中访问:

SELECT * from f_1BC9E55B5578456EB5ACABC99BB2FF0B_vacancies

导致错误

Microsoft Access 数据库引擎找不到输入表或查询“”。 确保它存在并且其名称拼写正确。

正如您所发现的,Access ODBC 将读取多个条目的键值并将它们显示为我们可以解析的分号分隔列表,但我们无法更新这些值

UPDATE Persons SET vacancies = '1;2' WHERE id = 1

失败了

UPDATE 或 DELETE 查询不能包含多值字段。 (-3209)

所以,TL;DR,如果您只需要从数据库中读取,那么您的解决方法可能就足够了,但是如果您需要修改这些多值字段,那么 Access ODBC 将无法为您完成工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM