我有以下三个类:
A
AItem
ACollection
。用户可以添加无限量的对象作为class A
的一部分。从A继承的每个对象都可以在class AItem
中添加无限量的对象。然后,用户可以根据需要制作这些项目的集合或组合。这些集合仅适用于属于AItem
A
colors = A
red = AI(colors)
green = AI(colors)
blue = AI(colors)
yellow = AI(colors)
black = AI(colors)
brown = AI(colors)
white = AI(colors)
Collection_1 = [red, green, blue]
Collection_2 = [brown, black]
Collection_3 = [red, brown, yellow]
的项目。请注意,并非A中的每个对象都必须具有集合,并且项目可以出现在多个集合中。
示例:
class A(db.model):
__tablename__ = 'a'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
a_items = db.relationship('AItem', backref='a')
class AItem(db.model):
__tablename__ = 'a_items'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
A_id = db.Column(db.Integer, db.ForeignKey('a.id'))
class ACollection(db.model):
__tablename__ = 'a_collections'
id = db.Column(db.Integer, primary_key=True)
我的代码到目前为止:
ACollection
我的问题:
如何构建{{1}}类?另外,请随意“重新设计”或重新考虑我的任何代码。
答案 0 :(得分:3)
我建议您从SQLAlchemy文档的Object Relational Tutorial部分开始,这将使您能够更好地理解所实现的OO概念以及所表示的数据结构。它解释了工作单元(会话),域模型和各种类型的关系。如果你只需要阅读一个页面(虽然非常大),这就是它。
但是为了让您入门,请参阅下面的自包含和运行代码,其中包含您的模型,包括多对多关系,插入,更新和删除数据。根据您的代码示例代码使用Flask和Flask-SQLAlchemy。
另外,我真的会给你的模型对象和关系提供其他名称:
A -> Category
AItem -> [Category]Item
ACollection -> [Item]Collection
A.a_items -> items (with backref *category*)
下面是代码,注释[out] SQLALCHEMY_ECHO
行以隐藏/查看已执行的SQL
语句。只需将其保存到某个python文件并运行它。
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
_db_uri = 'sqlite:///:memory:'
app.config['SQLALCHEMY_DATABASE_URI'] = _db_uri
app.config['SQLALCHEMY_ECHO'] = True # @TODO: uncomment to see SQL statements
db = SQLAlchemy(app)
# utility to make string representation of objects human-readable
def _repr(self):
from sqlalchemy.orm import class_mapper
attrs = class_mapper(self.__class__).column_attrs # only columns
# attrs = class_mapper(self.__class__).attrs # show also relationships
return u"<{}({})>".format(
self.__class__.__name__,
', '.join(
'%s=%r' % (k.key, getattr(self, k.key))
for k in sorted(attrs)
)
)
db.Model.__repr__ = _repr
# DEFINE THE MODEL
class A(db.Model):
__tablename__ = 'a'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
a_items = db.relationship('AItem', backref='a')
def get_item_by_name(self, item_name):
""" In memory search for the item of this class of given name. """
for item in self.a_items:
if item.name == item_name:
return item
class AItem(db.Model):
__tablename__ = 'a_items'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64), unique=True)
A_id = db.Column(db.Integer, db.ForeignKey('a.id'))
# this table contains many-to-many relationship
t_collection_item = db.Table(
'a_collection_item', db.Model.metadata,
db.Column('a_items_id', db.Integer, db.ForeignKey('a_items.id'),
primary_key=True),
db.Column('a_collections_id', db.Integer, db.ForeignKey('a_collections.id'),
primary_key=True)
)
class ACollection(db.Model):
__tablename__ = 'a_collections'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64))
items = db.relationship(AItem,
secondary=t_collection_item,
backref='collections')
def test_model():
with app.app_context():
db.create_all()
# CREATE SOME TEST DATA
# create instance of *A*
colors = A(name='colors')
smells = A(name='smells')
# add some items to them
colors.a_items = [
AItem(name='red'),
AItem(name='green'),
AItem(name='blue'),
AItem(name='yellow'),
AItem(name='black'),
]
smells.a_items = [
AItem(name='superb'),
AItem(name='awful')
]
# this will insert into DB instance of *A* and all their dependents
db.session.add(colors)
db.session.add(smells)
db.session.commit()
# create some collections, but first find colors
red = colors.get_item_by_name('red')
green = colors.get_item_by_name('green')
blue = colors.get_item_by_name('blue')
black = colors.get_item_by_name('black')
yellow = colors.get_item_by_name('yellow')
# create a new one
white = AItem(name='white')
colors.a_items.append(white)
coll1 = ACollection(name='my favorites', items=[red, green, blue])
coll2 = ACollection(name='i hate these', items=[black, yellow])
db.session.add_all([white, coll1, coll2])
db.session.commit()
# SOME QUERIES
# get collections which has blue color
q = (db.session.query(ACollection)
.join(AItem, ACollection.items)
.filter(AItem.name == 'blue')
)
for coll in q.all():
print(coll)
for item in coll.items:
print(" {}".format(item))
# Now I hate blue, so lets remove it from my collection and rename it
mycol = db.session.query(ACollection)\
.filter(ACollection.name == 'my favorites').one()
mycol.name = 'my new favorites'
mycol.items.remove(blue)
db.session.commit()
assert 2 == len(mycol.items)
if __name__ == '__main__':
test_model()
答案 1 :(得分:1)
您是否想要了解如何构建数据或类的建议?由于我不确定,我会给你们两个。
数据:强>
从数据的角度来看,我建议您在表a_items_collections
和a_items
之间创建一个表a_collections
,因为您有一个N到N的关系(一个集合可以有很多项目,一个项目可以属于许多集合)。因此,a_items_collections
的每一行都会在项目和集合之间建立链接。
<强> OOP:强>
从OOP的角度来看,您可以定义数据类。您可以在AItem
中设置ACollection
数组,您可以使用表a_items_collections
的另一个集合,...您当然应该使用ORM来帮助您这样做。我不是Python的专家,所以我在这里帮不了多少。另外,我强烈建议您使用SOA(面向服务的体系结构)模式将业务类与数据类分开。更清楚的是,数据库的数据类镜像应该只包含属性,操作这些数据的智能应该在其他类中实现(通常实现为singleton)。如果您必须以与商品相同的方式操纵收藏品,则可以查看composite模式。