gpt4 book ai didi

python - 如何使用 Flask-SQLAlchemy 使用 csv 填充具有外键的模型?

转载 作者:太空宇宙 更新时间:2023-11-03 11:32:07 26 4
gpt4 key购买 nike

我有 2 个模型类如下:

class Domain(db.Model):
__tablename__ = 'domain'
id = db.Column(db.Integer, primary_key=True)
domain_name = db.Column(db.String(30), unique=True)
mailboxes = db.Column(db.Integer, default=0)

def __init__(self, **kwargs):
self.__dict__.update(kwargs)

def __repr__(self):
return '%s' % self.domain_name


class EmailAccount(db.Model):
__tablename__ = 'email_account'
__table_args__ = (
db.UniqueConstraint('username', 'domain_id',
name='_uq_username_domain'),{}
)
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(30))
domain_id = db.Column(db.Integer, db.ForeignKey('domain.id'))
domain = db.relationship('Domain', backref=db.backref('emailaccounts',
lazy='dynamic'))
def __init__(self,**kwargs):
self.__dict__.update(kwargs)

def __repr__(self):
return '%s@%s ' % (self.username, self.domain)

我在示例中只添加了这里需要的相关属性。我希望通过读取数据的 csv 文件来使用脚本填充模型。 domain 表的脚本使用 Flask-SQLAlchemy 运行良好,但 emailaccount 表的脚本抛出异常。脚本如下:

#Populate domains from csv
domain_file = "domain.csv"
csv_file = csv.DictReader(open(domain_file, 'rb'), delimiter=',')
for row in csv_file:
#data type conversion from (csv)string before inserting to table
for key, value in row.items():
#some code omitted
print key, value
domain = Domain(**row)
db.session.add(domain)
db.session.commit()

#Populate accounts from csv
accounts_file = "accounts.csv"
csv_file = csv.DictReader(open(accounts_file, 'rb'), delimiter=',')

for row in csv_file:
mdomain_name = ''
#data type conversion from (csv)string before inserting to table
for key, value in row.items():
print key, value
if key == 'domain':
mdomain = Domain.query.filter_by(domain_name = value).first()
mdomain_name = mdomain.domain_name
mdomain_id = mdomain.id
if key == 'domain_id':
value = mdomain_id
account = EmailAccount(**row)
db.session.add(account)
db.session.commit()

抛出的异常是:

File "data.py", line 55, in db.session.add(account)
File ".../local/lib/python2.7/site-packages/sqlalchemy/orm/scoping.py", line 149, in do return getattr(self.registry(), name)(*args, **kwargs)
File ".../local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1397, in add self._save_or_update_state(state)
File ".../local/lib/python2.7/site-packages/sqlalchemy/orm/session.py", line 1415, in _save_or_update_state halt_on=self._contains_state):
File ".../local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1986, in cascade_iterator parent_dict, visited_states, halt_on))
File ".../local/lib/python2.7/site-packages/sqlalchemy/orm/properties.py", line 930, in cascade_iterator get_all_pending(state, dict_)
File ".../local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 761, in get_all_pending ret = [(instance_state(current), current)] AttributeError: 'str' object has no attribute '_sa_instance_state'

通过 data.py 脚本中代码的更改恢复,即用于为 EmailAccount 模型上传数据的脚本,该模型具有 Domain 类的外键。我只想使用 Flask-SQLAlchemy。

accounts.csv 文件的提取:

Email Account,legacy_username,password,full_name,quota,is_domain_admin,is_catch_all,disabled_login,disabled_delivery
info@abc.com,,,,104857600,,,,
internal@abc.com,,,Internal,102400000,,,,
kiran.rs@abc.com,,,,102400000,,,, kishorepr,xyz.com,,,,209715200,,,,

最佳答案

当一行包含 domain 键时,您检索域以获取其键,但您不使用域 ID 更新您的 row

然后当你这样做时:

account = EmailAccount(**row)

row 对象仍然具有与域名关联的键 domain。由于您的 EmailAccount 类使用名称 domain 作为关系,数据库认为它会得到一个 Domain 对象,而实际上,它得到一个 字符串(名称)。这就是您收到错误 AttributeError: 'str' object has no attribute '_sa_instance_state' 的原因。

更新:这应该有效

for row in csv_file:
account_values = {}
for key, value in row.items():
if key == 'domain':
mdomain = Domain.query.filter_by(domain_name = value).first()
account_values['domain'] = mdomain
else:
account_values[key] = value
account = EmailAccount(account_values)
db.session.add(account)
db.session.commit()

关于python - 如何使用 Flask-SQLAlchemy 使用 csv 填充具有外键的模型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16475741/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com