我“指数” SQLAlchemy的模型属性所以说我有一些类X,Y和Z使用的SQLAlchemy声明的语法来定义一些简单的列和关系怎么可能是主键和关系
要求:
在类级别,
(X|Y|Z).primary_keys
返回
各个类的主键(InstrumentedAttribute
对象)的集合我也想(X|Y|Z).relations
引用类的在同一 关系方式在实例级,我想同样的属性引用 这些属性实例化的价值观,他们是否已经 用自己的构造稀少,个别属性
制定者,或什么的SQLAlchemy做时,它从db检索 行。
到目前为止,我有以下几点。
import collections
import sqlalchemy
import sqlalchemy.ext.declarative
from sqlalchemy import MetaData, Column, Table, ForeignKey, Integer, String, Date, Text
from sqlalchemy.orm import relationship, backref
class IndexedMeta(sqlalchemy.ext.declarative.DeclarativeMeta):
"""Metaclass to initialize some class-level collections on models"""
def __new__(cls, name, bases, defaultdict):
cls.pk_columns = set()
cls.relations = collections.namedtuple('RelationshipItem', 'one many')(set(), set())
return super().__new__(cls, name, bases, defaultdict)
Base = sqlalchemy.ext.declarative.declarative_base(metaclass=IndexedMeta)
def build_class_lens(cls, key, inst):
"""Populates the 'indexes' of primary key and relationship attributes with the attributes' names. Additionally, separates "x to many" relationships from "x to one" relationships and associates "x to one" relathionships with the local-side foreign key column"""
if isinstance(inst.property, sqlalchemy.orm.properties.ColumnProperty):
if inst.property.columns[0].primary_key:
cls.pk_columns.add(inst.key)
elif isinstance(inst.property, sqlalchemy.orm.properties.RelationshipProperty):
if inst.property.direction.name == ('MANYTOONE' or 'ONETOONE'):
local_column = cls.__mapper__.get_property_by_column(inst.property.local_side[0]).key
cls.relations.one.add((local_column, inst.key))
else:
cls.relations.many.add(inst.key)
sqlalchemy.event.listen(Base, 'attribute_instrument', build_class_lens)
class Meeting(Base):
__tablename__ = 'meetings'
def __init__(self, memo):
self.memo = memo
id = Column(Integer, primary_key=True)
date = Column(Date)
memo = Column('note', String(60), nullable=True)
category_name = Column('category', String(60), ForeignKey('categories.name'))
category = relationship("Category", backref=backref('meetings'))
topics = relationship("Topic",
secondary=meetings_topics,
backref="meetings")
...
...
好了,通过让我在一流水平,但我觉得我做的傻事与元类,我也得到了一些奇怪的间歇性错误,其中“SQLAlchemy的”模块据称是无法识别build_class_lens
并且演变为Nonetype。
我不太清楚我应该如何在实例级别进行操作。 我查看了事件界面。我看到ORM事件init
,但它似乎在我的模型上定义的__init__
函数之前运行,这意味着实例属性当时尚未填充,所以我无法在其上创建“镜头”。 我也想知道属性事件set
可能有帮助。这是我的下一次尝试,但我仍然怀疑它是否是最合适的方式。
总而言之,我真的不知道我是否错过了一些非常优雅的方法来解决这个问题。