我「指數」 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
可能有幫助。這是我的下一次嘗試,但我仍然懷疑它是否是最合適的方式。
總而言之,我真的不知道我是否錯過了一些非常優雅的方法來解決這個問題。