hogeとはワイルドカードのようなものです。日々起こった、さまざまなこと −すなわちワイルドカード− を取り上げて日記を書く、という意味で名付けたのかというとそうでもありません。適当に決めたらこんな理由が浮かんできました。
11/18/2017 ふむ [長年日記]
tDiary 5504日目
■ [Py][小ネタ] SQLAlchemy でグラフ
相変わらず長いこと放置しているので,秋の夜長にと言うには少し遅いけど,何となく遊び.
ノードに種類を持たせつつ,多対多でノード同士を繋いでみたりするなど.
import uuid
import json
from contextlib import contextmanager
from sqlalchemy import create_engine
from sqlalchemy import Table, Column, ForeignKey, String
from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
Engine = create_engine('sqlite:///:memory:')
Session = sessionmaker(bind=Engine)
NodeAssoc = Table(
'node_assoc', Base.metadata,
Column('parent_id', String(36),
ForeignKey('node.id', onupdate='CASCADE', ondelete='CASCADE'),
nullable=False),
Column('child_id', String(36),
ForeignKey('node.id', onupdate='CASCADE', ondelete='CASCADE'),
nullable=False),
)
@contextmanager
def txn():
session = Session()
try:
yield session
session.commit()
except Exception:
session.rollback()
raise
finally:
session.close()
class ModelBase:
def __init__(self, **kwargs):
self.id = str(uuid.uuid4())
self.apply(**kwargs)
def apply(self, **kwargs):
for key, val in kwargs.items():
setattr(self, key, val)
def dictify(self, ignore=['id']):
return {n: getattr(self, n)
for n in self.__table__.columns.keys() if n not in ignore}
def __repr__(self):
return json.dumps(self.dictify())
class Node(ModelBase, Base):
TYPE = None
id = Column(String(36), primary_key=True)
type = Column(String(255), nullable=False)
value = Column(String(255))
children = relationship(
'Node', secondary=NodeAssoc,
primaryjoin=id == NodeAssoc.columns.parent_id,
secondaryjoin=id == NodeAssoc.columns.child_id,
backref='parents', uselist=True)
__tablename__ = 'node'
__mapper_args__ = {'polymorphic_on': type}
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.type = self.TYPE
class CircleNode(Node):
TYPE = 'circle'
__mapper_args__ = {'polymorphic_identity': TYPE}
class SquareNode(Node):
TYPE = 'square'
__mapper_args__ = {'polymorphic_identity': TYPE}
class TriangleNode(Node):
TYPE = 'triangle'
__mapper_args__ = {'polymorphic_identity': TYPE}
if __name__ == '__main__':
def dump(mode, nodes):
def _dump(mode, node, level=1):
print(' ' * level, node)
for n in getattr(node, mode):
_dump(mode, n, level + 2)
print(mode)
for node in nodes:
_dump(mode, node)
print()
Base.metadata.create_all(bind=Engine)
with txn() as session:
t1 = TriangleNode(value='1')
t2 = TriangleNode(value='2')
t3 = TriangleNode(value='3')
s1 = SquareNode(value='1', children=[t1, t2])
s2 = SquareNode(value='2', children=[t2, t3])
c1 = CircleNode(value='1', children=[s1, s2])
session.add(c1)
with txn() as session:
for mode, cls in [('children', CircleNode), ('parents', TriangleNode)]:
dump(mode, session.query(cls).all())
実行するとこうなる.
children
{"type": "circle", "value": "1"}
{"type": "square", "value": "1"}
{"type": "triangle", "value": "1"}
{"type": "triangle", "value": "2"}
{"type": "square", "value": "2"}
{"type": "triangle", "value": "2"}
{"type": "triangle", "value": "3"}
parents
{"type": "triangle", "value": "1"}
{"type": "square", "value": "1"}
{"type": "circle", "value": "1"}
{"type": "triangle", "value": "2"}
{"type": "square", "value": "2"}
{"type": "circle", "value": "1"}
{"type": "square", "value": "1"}
{"type": "circle", "value": "1"}
{"type": "triangle", "value": "3"}
{"type": "square", "value": "2"}
{"type": "circle", "value": "1"}
だからどうしたぼくドラえもん.
クワッ!!って、来たら、ササッとやってスッ…て、避けたら、おぉっ!
って、感じですな。
これはこれで、趣がありますな。
ただ、お風呂の物体X…。
あの頃の、インパクト成分が、もう少し、あっても良いと思う。
ちなみに近況報告。
atzmもっさり元気してる?
こっちは、もっさもっさしてる。安定のいっぱいいっぱいさね。
windowsSE98.英国仕様
心踊りますな。
あけおめ.
明鏡止水の心持ちにて真を見れば,風呂の物体もホットプレートの浮島も泡沫夢幻の如く盛者必衰の理を表して候えばありをりはべりいまそかり.