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)
上一篇下一篇

猜你喜欢

热点阅读