Sqlalchemy 炼金术中一对一关系的实现
我是一个没有经验的程序员。我想在用户和货币之间添加一对一关系CurrencyDefault(该值将分配给FlaskForm中的字段):Sqlalchemy 炼金术中一对一关系的实现,sqlalchemy,flask-sqlalchemy,Sqlalchemy,Flask Sqlalchemy,我是一个没有经验的程序员。我想在用户和货币之间添加一对一关系CurrencyDefault(该值将分配给FlaskForm中的字段): class User(UserMixin, db.Model): id = db.Column(db.Integer, db.Sequence('user_id_seq'), primary_key=True) username = db.Column(db.String(64), index=True, unique=True) ema
class User(UserMixin, db.Model):
id = db.Column(db.Integer, db.Sequence('user_id_seq'), primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(64), index=True, unique=True)
pswd_hash = db.Column(db.String(128))
expenses = db.relationship('Expense', backref='user')
currency = db.relationship('Currency', backref='user')
curr_default = ?
# ...
class Currency(db.Model):
id = db.Column(db.Integer, db.Sequence('expense_id_seq'), primary_key=True)
abbr = db.Column(db.String(10))
name = db.Column(db.String(64))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
default = ?
# ...
我想要实现的是为每个用户.id
分配一个货币.id
(一对一)
我想征求一些建议,最好的做法是什么
考虑到这个问题后,我有如下想法:
class User(UserMixin, db.Model):
id = db.Column(db.Integer, db.Sequence('user_id_seq'), primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(64), index=True, unique=True)
pswd_hash = db.Column(db.String(128))
currency_default_choice = db.Column(db.Integer, b.ForeignKey('currency.id'))
expenses = db.relationship('Expense', backref='user')
currency = db.relationship('Currency', backref='user', foreign_keys="Currency.user_id")
# currency_default = db.relationship(
# 'Currency',
# foreign_keys='User.currency_default_choice',
# backref='currency_default',
# uselist=False,
# )
# ...
class Currency(db.Model):
id = db.Column(db.Integer, db.Sequence('expense_id_seq'), primary_key=True)
abbr = db.Column(db.String(10), b.ForeignKey('currency_official_abbr.abbr'))
name = db.Column(db.String(64))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
currency_default = db.relationship(
'User',
foreign_keys='User.currency_default_choice',
backref='currency_default',
uselist=False,
)
其他用户创建的Currency.id
对象设置为Currency\u default\u choice
。如何将currency\u default\u选项
仅限于此用户创建的
User
类(currency\u default\u choice=db.Column(db.Integer,b.ForeignKey('currency.id'))
)中设置具有ForeignKey
的关系与以下设置有什么区别:用户
侧设置此关系:
class User(db.Model):
# ...
currency_default = db.relationship(
'Currency',
foreign_keys='User.currency_default_choice',
backref='currency_default',
uselist=False,
)
公元2年。在我看来,这两种方法之间没有区别,因为backref
参数暗示了双向行为
,所以我是否将db.relationship()
放在User
或Currency
类中并不重要。对吗
用户.currency\u默认值添加了值
这听起来像是一种多对一的关系。(许多
用户
共享相同的货币
选择。因此在用户
模型中会有一个货币id
。不,这是一对一的,因为每个用户
都可以使用唯一id创建自己的货币
,并且只能访问他创建的货币。uselist False
不是他通常的做法是——有一个关于SQLAlchemy的例子用于设置。我会将默认值存储在用户端,因为这样会更清楚(user.default\u currency\u choice),节省一点空间,并保存一个查询以每次计算出默认值。
class User(db.Model):
# ...
currency_default = db.relationship(
'Currency',
foreign_keys='User.currency_default_choice',
backref='currency_default',
uselist=False,
)
>>> app = create_app()
>>> app.app_context().push()
>>> admin = User.query.filter_by(username='admin').first()
<User(id= 1, username = admin, email = admin@admin.com)
>>> currency = Currency.query.filter_by(user=admin)
>>> currency
<flask_sqlalchemy.BaseQuery object at 0x03EA05D0>
>>> currency[0].id
1
>>> admin.currency_default = currency[0]
>>> db.session.commit()
>>> currency[0].currency_default
<User(id= 1, username = admin, email = admin@admin.com)
>>> admin.currency_default_choice
1
sqlalchemy.exc.CircularDependencyError: Circular dependency detected.
(ProcessState(OneToManyDP(Currency.currency_default),
<Currency at 0x46542b0>, delete=False),
ProcessState(ManyToOneDP(User.currency_default),
<User at 0x4669b10>, delete=False),
SaveUpdateState(<Currency at 0x46542b0>),
ProcessState(OneToManyDP(User.currency), <User at 0x4669b10>, delete=False),
SaveUpdateState(<User at 0x4669b10>))