标签: flask-sqlalchemy

Flask:如何管理不同的环境数据库?

我正在开发一个类似的应用程序

facebook/
         __init__.py
         feed/
             __init__.py
             business.py
             views.py
             models/
                    persistence.py
                    user.py
         chat/
             __init__.py
             models.py
             business.py
             views.py
         config/
                dev.py
                test.py
                prod.py 
Run Code Online (Sandbox Code Playgroud)

我希望有三个环境Dev,Test并且Production.
我有以下要求:
A)当我启动服务器.python runserver.py,我想提一提我想要的环境,连接- Dev,TestProduction.
b.)Dev&Production应该建立架构,只需要连接到机器
c.)我也想让我的测试连接到sqlite db,并创建架构,运行测试

如何以配置方式实现此目的,以便我不必硬编码与数据库相关的任何内容.

烧瓶中是否有任何好的图案?

目前我runerver.py的环境硬编码我不喜欢,

app = Flask(__name__)
app.config['SECRET_KEY'] = dev.SECRET_KEY
Run Code Online (Sandbox Code Playgroud)

我正在寻找比我更好的想法

python flask flask-sqlalchemy

11
推荐指数
2
解决办法
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-Migrate sqlalchemy.exc.NoReferencedTableError:与列关联的外键

我在我的应用程序中使用Flask-Migrate,具有以下模型:

listpull/models.py

from datetime import datetime

from listpull import db


class Job(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    list_type_id = db.Column(db.Integer, db.ForeignKey('listtype.id'),
                             nullable=False)
    list_type = db.relationship('ListType',
                                backref=db.backref('jobs', lazy='dynamic'))
    record_count = db.Column(db.Integer, nullable=False)
    status = db.Column(db.Integer, nullable=False)
    sf_job_id = db.Column(db.Integer, nullable=False)
    created_at = db.Column(db.DateTime, nullable=False)
    compressed_csv = db.Column(db.LargeBinary)

    def __init__(self, list_type, created_at=None):
        self.list_type = list_type
        if created_at is None:
            created_at = datetime.utcnow()
        self.created_at = created_at

    def __repr__(self):
        return '<Job {}>'.format(self.id)


class ListType(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True, nullable=False)

    def __init__(self, …
Run Code Online (Sandbox Code Playgroud)

sqlalchemy sqlalchemy-migrate flask flask-sqlalchemy flask-migrate

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

使用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
查看次数

为什么这个被弃用的Factory.set_creation_function的替代品不能与nosetests一起使用?

Factory Boy弃用了set_creation_function(参见ChangeLog 2.6.1)并建议开发人员

使用SomeFactory的_create()方法的替换替换factory.set_creation_function(SomeFactory,creation_function)

我有i)一些衍生工厂类和ii)我的数据库会话在另一个模块中实例化,所以我尝试用下面的第二个代码块替换https://github.com/mattupstate/overholt中的工作示例.PyCharm警告我"db"导入没有被使用,所以我怀疑在设置sqlalchemy_session时可能没有正确解除引用?

使用nosetests 1.3.7(但现在不推荐使用FactoryBoy的set_creation_function):

from myapp.core import db

def create_sqlalchemy_model_function(class_to_create, *args, **kwargs):
    entity = class_to_create(**kwargs)
    db.session.add(entity)
    db.session.commit()
    return entity

Factory.set_creation_function(create_sqlalchemy_model_function)
Run Code Online (Sandbox Code Playgroud)

不使用nosetests 2.x(看起来db没有被正确引用?)

from factory.alchemy import SQLAlchemyModelFactory as Factory
from myapp.core import db

class Factory():
    class Meta:
        sqlalchemy_session = db.session

    def _create(cls, model_class, *args, **kwargs):
        entity = model_class(*args, **kwargs)
        db.session.add(entity)
        db.session.commit()
        return entity
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy nose flask flask-sqlalchemy

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

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
查看次数

如何使用 SqlAlchemy 在 Postgres 中查询 JSON 数组?

我定义了一个 SqlAlchemy 模型

from sqlalchemy.dialects.postgresql import JSONB

class User(db.Model):
    __tablename__ = "user"
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(255), nullable=False)
    city = db.Column(db.String(255))
    contact_list = db.Column(JSONB)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

def add_user():
    user = User(nickname="Mike")
    user.contact_list = [{"name": "Sam", "phone": ["123456", "654321"]}, 
                         {"name": "John", "phone": ["159753"]},
                         {"name": "Joe", "phone": ["147889", "98741"]}]
    db.session.add(user)
    db.session.commit()

if __name__ == "__main__":
    add_user()
Run Code Online (Sandbox Code Playgroud)

如何使用电话从我的contact_list 中检索姓名?例如,我有147889,我如何检索Joe

我试过这个

User.query.filter(User.contact_list.contains({"phone": ["147889"]})).all()

但是,它返回给我一个空列表, []

我怎样才能做到这一点?

sqlalchemy flask-sqlalchemy

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

在运行 db init 时将记录添加到表中

我正在为我的应用程序使用 Flask、sqlalchemy、sqlite 和 python。当我运行 db init 以创建数据库时,我希望将一些默认值集添加到数据库中。我已经尝试了这两件事来将记录添加到表中。一种方法是使用“事件”。

from sqlalchemy.event import listen
from sqlalchemy import event, DDL

@event.listens_for(studentStatus.__table__, 'after_create')
def insert_initial_values(*args, **kwargs):
    db.session.add(studentStatus(status_name='Waiting on admission'))
    db.session.add(studentStatus(status_name='Waiting on student'))
    db.session.add(studentStatus(status_name='Interaction Initiated'))
    db.session.commit()

Run Code Online (Sandbox Code Playgroud)

当我跑

python manage_db.py db init,
python manage_db.py db migrate,
python manage_db.py db upgrade
Run Code Online (Sandbox Code Playgroud)

我没有遇到任何问题,但没有创建记录。

我尝试的另一种方法是,在我包含的models.py中

record_for_student_status = studentStatus(status_name="Waiting on student")
db.session.add(record_for_student_status)
db.session.commit()
print(record_for_student_status)
Run Code Online (Sandbox Code Playgroud)

类模型代码:

class StudentStatus(db.Model): 
   status_id = db.Column(db.Integer,primary_key=True) 
   status_name = db.Column(db.String) 
   def __repr__(self): 
      return f"studentStatus('{self.status_id}','{self.status_name}')" 
Run Code Online (Sandbox Code Playgroud)

当我运行 python manage_db.py db init 时,出现错误 Student_status,没有这样的表。

有人可以帮助我在运行 db init 时如何将默认值添加到 student_status 表中吗?

我也试过烧瓶播种机。我已经安装了flask …

sqlite sqlalchemy flask python-3.x flask-sqlalchemy

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