SQLALchemy踩坑日志
2019-09-24 本文已影响0人
周末的游戏之旅
立个flag,这篇文章我会记录下我在用SQLALchemy中遇到的所有问题。另外,前端太难了,我是真的写不来😭
最近的爬虫项目需要添加用户操作,毕竟用命令和SQL管理数据太麻烦了。
朋友推荐用Flask,一个简单的web框架,我在对接mysql的时候遇到了很多问题,记一下。
flask对接MySQL是用的flask-sqlalchemy扩展。sqlalchemy是一个ORM(概念百度吧)。
以前没用过这个,现在需要将两个表做连接查询,用sql的话直接join就完事了(以前都是用pymysql)。
这个就比较麻烦了,需要在连接查询的表中做好外键和连接
表1,需要在表1中指明外键
class scan_result(db.Model):
__tablename__ = 'scan_result'
__table_args__ = {"useexisting": True}
scan_id = db.Column(db.Integer, primary_key = True, autoincrement = True)
url_id = db.Column(db.Integer, db.ForeignKey('list_url.url_id'), index=True)
description = db.Column(db.String(255))
type_id = db.Column(db.Integer, db.ForeignKey('url_type.type_id'))
time = db.Column(db.DateTime)
def __repr__(self):
print("<scan_result(scan_id=%d, description='%s')>" % (self.scan_id, self.description))
表2,需要用relationship做好连接,注意这里要用backref指明关联属性的名字,例如我这里的url。这样在用scan_result做连接查询时就会自动在scan_result中创建url属性,通过url属性就可以拿到连接查询后对应的字段了。
很多教程中这里没有用bakcref做连接,而是直接
.query(table1).join(table2)
,我尝试这样做的时候发现只能拿到table1中的字段,table2中的字段是拿不到的。也可能是flask-sqlalchemy更新了。
190925更新:backref的值要注意不能和models模块下的任意类中的任意字段重名,否则会报:该属性属于xxxClass的错误
class list_url(db.Model):
__tablename__ = 'list_url'
__table_args__ = {"useexisting": True}
url_id = db.Column(db.Integer, primary_key = True, autoincrement=True)
url = db.Column(db.String(255))
realurl = db.Column(db.String(255))
scan = db.relationship('app.models.scan_result',backref='url')
def __repr__(self):
print("<list_url(url='%s',realurl='%s')>" % (self.url,self.realurl))
完整代码
from app import db
class scan_result(db.Model):
__tablename__ = 'scan_result'
__table_args__ = {"useexisting": True}
scan_id = db.Column(db.Integer, primary_key = True, autoincrement = True)
url_id = db.Column(db.Integer, db.ForeignKey('list_url.url_id'), index=True)
description = db.Column(db.String(255))
type_id = db.Column(db.Integer, db.ForeignKey('url_type.type_id'))
time = db.Column(db.DateTime)
def __repr__(self):
print("<scan_result(scan_id=%d, description='%s')>" % (self.scan_id, self.description))
class list_url(db.Model):
__tablename__ = 'list_url'
__table_args__ = {"useexisting": True}
url_id = db.Column(db.Integer, primary_key = True, autoincrement=True)
url = db.Column(db.String(255))
realurl = db.Column(db.String(255))
scan = db.relationship('app.models.scan_result',backref='url')
def __repr__(self):
print("<list_url(url='%s',realurl='%s')>" % (self.url,self.realurl))
class url_type(db.Model):
__table_args__ = {"useexisting": True}
type_id = db.Column(db.Integer, primary_key = True, autoincrement=True)
name = db.Column(db.String(255))
scan_result = db.relationship('app.models.scan_result',backref='type')
def __repr__(self):
print("<url_type(name='%s')>" % (self.name))
sr = scan_result.query.all()
print(sr[0].url)