标签: flask-sqlalchemy

Python Flask-WTF - 使用相同的表单模板进行添加和编辑操作

我刚刚开始使用Flask/Flask-WTF/SQLAlchemy,我看到的大多数示例CRUD代码都显示了用于添加/编辑的单独模板.有两个模板几乎完全相同的形式html似乎重复(例如books_add.html,books_edit.html).从概念上讲,拥有一个模板(例如"books_form.html")对我来说更有意义,只需从两个单独的路径定义中调用同一模板上的render_template.我不太确定如何实现它,例如:

@app.route('/books/add')
def add_book():
...
render_template('books_form.html', action = 'add')


@app.route('/books/edit/<id>')
def edit_book(id):
...
render_template('books_form.html', action = 'edit', id = id)
Run Code Online (Sandbox Code Playgroud)

但我不确定我是否走上了正确的轨道,或者偏离了最佳实践.任何输入都很受欢迎 - 关于如何处理单个模板文件以处理添加或编辑行为的具体想法.也欢迎链接到示例.

谢谢!

python flask flask-sqlalchemy flask-wtforms

12
推荐指数
1
解决办法
9314
查看次数

Flask-SQLAlchemy查询连接关系表

我正在使用Flask和SQLAlchemy构建一个应用程序.我基本上有3个表:用户,友谊和bestFriends:

用户可以拥有许多朋友,但只有一个最好的朋友.所以我希望我的模型是关系型的."一对多"用于"用户"和"友谊"之间的关系以及"用户"和"最佳朋友"之间的"一对一"关系.

这是我的模特:

from app import db
from sqlalchemy.orm import relationship, backref
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.ext.declarative import declarative_base

class users(db.Model):

    __tablename__ = "Users"

    id = db.Column(db.Integer, primary_key=True)
    userName = db.Column(db.String, nullable=False)
    userEmail = db.Column(db.String, nullable=False)
    userPhone = db.Column(db.String, nullable=False)
    userPass = db.Column(db.String, nullable=False)

    friendsR = db.relationship('friendships', backref='friendships.friend_id', primaryjoin='users.id==friendships.user_id', lazy='joined')

    def __init__(self, userName, userEmail, userPhone, userPass):
        self.userName = userName
        self.userEmail = userEmail
        self.userPhone = userPhone
        self.userPass = userPass

    def __repr__(self):
        return '{}-{}-{}-{}'.format(self.id, self.userName, self.userEmail, self.userPhone)

class …
Run Code Online (Sandbox Code Playgroud)

join sqlalchemy flask flask-sqlalchemy

12
推荐指数
1
解决办法
4万
查看次数

Sqlalchemy按列表中的字段过滤但保留原始订单?

我有一个像这样的鞋子模型:

class Shoe(db.Model):
id = db.Column(db.Integer, primary_key = True)
asin = db.Column(db.String(20), index = True)
Run Code Online (Sandbox Code Playgroud)

我有一个像ids = [2,1,3]的id列表,当我在Shoe模型上查询结果在'ids'列表中有id时,我想回来:[{id:2,asin:" 111"},{id:1,asin:"113"},{id:3,asin:"42"}]但问题是使用以下查询语句不保留原始顺序,结果将会到来随机回来.如何保持我过滤的列表顺序?

不正确的一个: Shoe.query.filter(Shoe.id.in_(my_list_of_ids)).all()

python sqlalchemy flask-sqlalchemy

12
推荐指数
2
解决办法
2万
查看次数

SQLAlchemy中Session和db.session有什么区别?

在事件映射器级别文档中 它表示Session.add()不支持,但当我尝试在db.session.add(some_object)内部after_insert事件中工作时,例如:

def after_insert_listener(mapper, connection, user):
    global_group = Group.query.filter_by(groupname='global').first()
    a = Association(user,global_group)
    db.session.add(a)

event.listen(User, 'after_insert', after_insert_listener)
Run Code Online (Sandbox Code Playgroud)

基本上任何新用户都应该是global_group的一部分,所以我在after_insert事件中添加了它.我试图插入一个用户,然后检查我的数据库,我找到了用户记录和关联记录.

python sqlalchemy flask flask-sqlalchemy

12
推荐指数
1
解决办法
4117
查看次数

为 pytest 模拟 Sqlalchemy 会话

我不知道这是否可以完成,但我正在尝试模拟我的 db.session.save。

我正在使用烧瓶和烧瓶炼金术。

数据库文件

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()
Run Code Online (Sandbox Code Playgroud)

单元测试

def test_post(self):
    with app.app_context():
        with app.test_client() as client:
            with mock.patch('models.db.session.save') as mock_save:
                with mock.patch('models.db.session.commit') as mock_commit:

                    data = self.gen_legend_data()
                    response = client.post('/legends', data=json.dumps([data]), headers=access_header)

                    assert response.status_code == 200
                    mock_save.assert_called()
                    mock_commit.assert_called_once()
Run Code Online (Sandbox Code Playgroud)

和方法:

def post(cls):
    legends = schemas.Legends(many=True).load(request.get_json())

    for legend in legends:
        db.session.add(legend)

    db.session.commit()

    return {'message': 'legends saved'}, 200
Run Code Online (Sandbox Code Playgroud)

我正在尝试模拟 db.session.add 和 db.session.commit。我试过db.session.savelegends.models.db.session.savemodels.db.session.save。他们都带着保存错误回来了:

ModuleNotFoundError: No module named 'models.db.session'; 'models.db' is not a package
Run Code Online (Sandbox Code Playgroud)

我没有收到错误,也不知道如何解决。 …

python sqlalchemy mocking pytest flask-sqlalchemy

12
推荐指数
1
解决办法
1万
查看次数

测试期间创建Flask-Admin蓝图

我正在测试我的应用时,我在使用Flask-Admin创建蓝图时遇到了麻烦.

这是我的View类(使用SQLAlchemy)

##
# All views that only admins are allowed to see should inherit from this class.
#
class AuthView(ModelView):
    def is_accessible(self):
        return current_user.is_admin()

class UserView(AuthView):
    column_list = ('name', 'email', 'role_code')
Run Code Online (Sandbox Code Playgroud)

这是我初始化视图的方式:

# flask-admin
admin.add_view(UserView(User, db.session))
admin.init_app(app)
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试运行多个测试(故障总是发生在第二个测试和随后的所有其他测试)时,我总是收到以下错误消息:

======================================================================
ERROR: test_send_email (tests.test_views.TestUser)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/lib/python2.7/site-packages/nose/case.py", line 133, in run
    self.runTest(result)
  File "/lib/python2.7/site-packages/nose/case.py", line 151, in runTest
    test(result)
  File "/lib/python2.7/site-packages/flask_testing.py", line 72, in __call__
    self._pre_setup()
  File "/lib/python2.7/site-packages/flask_testing.py", line 80, in _pre_setup
    self.app = self.create_app()
  File …
Run Code Online (Sandbox Code Playgroud)

python flask flask-sqlalchemy flask-admin

11
推荐指数
2
解决办法
3076
查看次数

OperationalError:MySQL连接不可用

我正在使用Flask-SQLAlchemy 1.0,Flask 0.10,SQLAlchemy 0.8.2和Python 2.7.5.我正在使用Oracle的MySQL Connector/Python 1.0.12连接MySQL 5.6.

当我重新启动我的Web服务器(Apache2或Flask的内置)时,我OperationalError: MySQL Connection not available在MySQL wait_timeout过期后收到异常(默认为8小时).

我发现有类似问题并明确设置的人SQLALCHEMY_POOL_RECYCLE = 7200,即使这是Flask-SQLAlchemy的默认设置.当我在这里放置断点时,我看到拆解功能session.remove()在每个请求后成功调用.有任何想法吗?

2014年7月21日更新:

由于这个问题继续受到关注,我必须补充一点,我确实尝试了一些提案.我的两次尝试看起来如下:

第一:

@contextmanager
def safe_commit():
    try:
        yield
        db.session.commit()
    except:
        db.session.rollback()
        raise
Run Code Online (Sandbox Code Playgroud)

这允许我像这样包装我的提交调用:

with safe_commit():
    model = Model(prop=value)
    db.session.add(model)
Run Code Online (Sandbox Code Playgroud)

我99%肯定我没有错过db.session.commit这种方法的任何电话,我仍然有问题.

第二:

def managed_session():
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            try:
                response = f(*args, **kwargs)
                db.session.commit()
                return response
            except:
                db.session.rollback()
                raise
            finally:
                db.session.close()
        return decorated_function
    return decorator …
Run Code Online (Sandbox Code Playgroud)

python mysql sqlalchemy flask flask-sqlalchemy

11
推荐指数
2
解决办法
7111
查看次数

使用Flask-SQLAlchemy批量插入

我正在使用Flask-SQLAlchemy来做一个相当大的60k行的批量插入.我在这张桌子上也有多对多的关系,所以我不能用db.engine.execute它.在插入之前,我需要在数据库中找到类似的项目,如果找到重复的项目,则将插入更改为更新.

我可以事先做这个检查,然后通过插件进行批量插入db.engine.execute,但是在插入时我需要该行的主键.

目前,我做了db.session.add(),并db.session.commit()在每次插入,我也得到每秒进账3-4插入.

我运行了一个分析器,看看瓶颈在哪里,似乎db.session.commit()占用了60%的时间.

有没有什么方法可以让我更快地完成这个操作,可能是通过分组提交,但是哪个会给我主键?

这就是我的模型:

class Item(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(1024), nullable=True)
    created = db.Column(db.DateTime())
    tags_relationship = db.relationship('Tag', secondary=tags, backref=db.backref('items', lazy='dynamic'))
    tags = association_proxy('tags_relationship', 'text')

class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
text = db.Column(db.String(255))
Run Code Online (Sandbox Code Playgroud)

我的插入操作是这样运行的:

for item in items:
    if duplicate:
        update_existing_item
    else:
        x = Item()
        x.title = "string"
        x.created = datetime.datetime.utcnow()
        for tag in tags:
            if not tag_already_exists:
                y = Tag()
                y.text = "tagtext"
                x.tags_relationship.append(y) …
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy flask flask-sqlalchemy

11
推荐指数
2
解决办法
4844
查看次数

alembic生成物化视图

TL; DR:我如何让sqmbic理解并为sqlalchemy中创建的物化视图生成SQL?

我正在使用flask-sqlalchemy并使用alembic和postgres.为了获得使用sqlalchemy的物化视图,我在该主题上发表了一篇很好的帖子.我使用它很多,只有一些小的分歧(文章也使用flask-sqlalchemy,但完整的代码示例直接使用sqlalchemy的声明性基础).

class ActivityView(db.Model):
    __table__ = create_materialized_view(
        'activity_view',
        db.select([
            Activity.id.label('id'),
            Activity.name.label('name'),
            Activity.start_date.label('start_date'),
        ]).where(
            db.and_(
                Activity.start_date != None,
                Activity.start_date <=
                    datetime_to_str(datetime.now(tz=pytz.UTC) + timedelta(hours=48))
            )
        )
    )

    @classmethod
    def refresh(cls, concurrently=True):
        refresh_materialized_view(cls.__table__.fullname, concurrently)

db.Index('activity_view_index',
         ActivityView.__table__.c.id, ActivityView.__table__.c.start_date,
         unique=True)
Run Code Online (Sandbox Code Playgroud)

这些create_materialized_viewrefresh_materialized_view方法直接来自博客文章.

请注意,上面的示例已经大大简化,并且由于我的简化可能看起来很愚蠢,但我想要了解的真正想法是如何在迁移期间将alembic转换为一系列的alembic操作

当我运行测试时,代码运行正常,视图生成正常,一切正常.当alembic运行时,它不会对视图执行任何操作.所以我最终要做的是将测试为物化视图发出的SQL复制到alembic迁移/版本文件中,然后最终直接执行:

op.execute(activities_view_sql)
Run Code Online (Sandbox Code Playgroud)

类似地,我在物化视图上生成唯一索引时执行相同的直接SQL执行.

不幸的是,我的方法容易出错,并且会产生看似不必要的代码重复.

有没有办法让alembic了解我,ActivityView以便任何时候它改变,alembic将知道如何更新视图?

非常感谢!

sqlalchemy flask flask-sqlalchemy alembic

11
推荐指数
2
解决办法
636
查看次数

如何查询多个多态继承表的关系?

假设您有以下简化示例模式,它使用SQLAlchemy加入表多态继承.EngineerAnalyst模特有Role关系.该Intern模型没有.

class Role(db.Model):

    __tablename__ = 'role'

    id = db.Column(db.Integer, primary_key=True)

    name = db.Column(db.String(16), index=True)

class EmployeeBase(db.Model):

    __tablename__ = 'employee_base'

    id = db.Column(db.Integer, primary_key=True)

    some_attr = db.Column(db.String(16))
    another_attr = db.Column(db.String(16))

    type = db.Column(db.String(50), index=True)

    __mapper_args__ = {
        'polymorphic_identity': 'employee',
        'polymorphic_on': type
    }

class Engineer(EmployeeBase):

    __tablename__ = 'engineer'

    id = db.Column(db.Integer, db.ForeignKey('employee_base.id'), primary_key=True)

    role_id = db.Column(db.Integer, db.ForeignKey('role.id'), index=True)
    role = db.relationship('Role', backref='engineers')

    __mapper_args__ = {
        'polymorphic_identity': 'engineer',
    }

class Analyst(EmployeeBase):

    __tablename__ = 'analyst'

    id …
Run Code Online (Sandbox Code Playgroud)

sqlalchemy flask-sqlalchemy

11
推荐指数
1
解决办法
485
查看次数