![](/img/trans.png)
[英]How do I model a many-to-many relationship over 3 tables in SQLAlchemy (ORM)?
[英]How to model many-to-many database with 3 tables
我在 django 后端工作,我正在尝试对数据库建模并希望以最佳实践方式进行。 我需要一个“用户”表、一个“投资组合”表和一个“股票”表。 一个用户可以有多个投资组合,其中包含多只股票。
到目前为止,这是我的代码:
class User(models.Model):
user_id = models.AutoField(primary_key=True)
username = models.CharField(max_length=25)
in_cash = models.DecimalField(max_digits=15, decimal_places=2)
class Portfolios(models.Model):
portfolio_id = models.AutoField(primary_key=True)
user_id = models.ForeignKey("User", on_delete=models.CASCADE)
stock_id = models.ForeignKey("Stocks", on_delete=models.CASCADE)
buy_datetime = models.DateTimeField(default=datetime.now, blank=True)
number_of_shares = models.IntegerField()
class Stocks(models.Model):
stock_id = models.AutoField(primary_key=True)
stock_symbol = models.CharField(max_length=12)
在我的脑海中,我会在投资组合中的每只股票的“投资组合”表中都有一个条目。 所以“投资组合”看起来像
所以有一个投资组合,其中包含两只股票。 但总的来说,这似乎不对。 如果像我上面的例子那样使用,我不能将 portfolioid 作为主键,我该如何改进呢?
谢谢你的时间
与通常的多对多情况一样,您需要创建一个intermediary table
,也称为junction table/association table
。 关联实体
您的用户将拥有多个投资组合:
class UserPortfolio(models.Model):
user_id = models.ForeignKey("User")
portfolio_id = models.ForeignKey("Portfolio")
投资组合中将有多只股票:
class PortfolioStock(models.Model):
portfolio_id = models.ForeignKey("Portfolio")
stock_id = models.ForeignKey("Stock")
现在一个用户可以拥有多个投资组合,而这些投资组合将包括多只股票。 为了访问用户的相应股票,您需要加入表格。
令我困惑的是portfolio这个名字,我称之为position 。 您的初始代码是正确的,尽管我对其进行了一些更改,删除了可能不需要的AutoField
,使用OneToOneField
将Customer
连接到User
,删除了类名末尾的s ,它们是模板,因此应该是单数,也不是复数,为Stock
增加price
。 最后更改Portfolio
,它应该是所有Position
的总和。
from django.conf import settings
class Customer(models.Model):
customer = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,)
in_cash = models.DecimalField(max_digits=15, decimal_places=2)
def __str__(self):
return self.customer.username
class Position(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
stock = models.ForeignKey('Stock', on_delete=models.CASCADE)
number_of_shares = models.IntegerField()
buy_datetime = models.DateTimeField(default=datetime.now, blank=True)
def __str__(self):
return self.customer.customer.username + ": " + str(self.number_of_shares) + " shares of " + self.stock.stock_symbol
class Stock(models.Model):
stock_symbol = models.CharField(max_length=12)
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return self.stock_symbol
在我的脑海中,我会在投资组合中的每只股票的“投资组合”表中都有一个条目。 所以“投资组合”看起来像
portfolioid 1, userid: 1, stockid: 1, buydate: 12.01.2019, shares: 20 portfolioid 1, userid: 1, stockid: 2, buydate: 19.02.2020, shares: 41
所以有一个投资组合,其中包含两只股票。 但总的来说,这似乎不对。 如果像我上面的例子那样使用,我不能将 portfolioid 作为主键,我该如何改进呢?
你是对的,除了应该应用于Position ,每个 Position 都是唯一的,而不是Portfolio
,这是Customer
拥有的所有Position
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.