如何围绕现有数据库构建烧瓶应用程序?

Ind*_*pta 64 python mysql sqlalchemy flask flask-sqlalchemy

我已经有一个现有的数据库,里面有很多表和很多数据MySQL.我打算创建一个Flask应用程序并使用sqlalchemy.现在我问了irc并在google上四处寻找并尝试了以下想法:

首先,我使用sqlacodegen从我的生成模型DB.但后来我对此感到困惑,看了一下.我找到了这个.

这看起来像一个优雅的解决方案

所以其次,我models.py根据那里的解决方案改写了我,现在我更加困惑.我正在寻找最好的方法来构建这个烧瓶应用程序以及现有的数据库.

我查看了烧瓶文档但是对于已经存在的db的项目没有真正得到任何帮助.从头开始创建内容有很多好东西,创建数据库和所有内容.但我真的很困惑.

请注意它是我的第一天Flask,但我有经验Django,所以基本概念不是障碍.我需要一些指导来为这个用例选择最佳方法.非常感谢详细解释.通过详细说明我绝对不希望有人写下所有的代码和勺子喂我这个,但足以让我开始,这是将这个数据库无缝地集成到flaskvia中sqlalchemy.注意我的数据库在MySQL.

Hol*_*rig 91

我说你的问题与烧瓶完全无关.例如,模板,路径,视图或登录装饰器没有问题.

你在哪里挣扎在SQLAlchemy.

所以我的建议是暂时忽略Flask并首先习惯SQLAlchemy.您需要习惯现有数据库以及如何从SQLAlchemy访问它.使用一些MySQL文档工具来找到解决方法.这样的开头(请注意,它与Flask无关,请求所有......):

#!/usr/bin/python
# -*- mode: python -*-

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///webmgmt.db', convert_unicode=True, echo=False)
Base = declarative_base()
Base.metadata.reflect(engine)


from sqlalchemy.orm import relationship, backref

class Users(Base):
    __table__ = Base.metadata.tables['users']


if __name__ == '__main__':
    from sqlalchemy.orm import scoped_session, sessionmaker, Query
    db_session = scoped_session(sessionmaker(bind=engine))
    for item in db_session.query(Users.id, Users.name):
        print item
Run Code Online (Sandbox Code Playgroud)

在" engine =" 行中,您需要提供MySQL数据库的路径,以便SQLAlchemy找到它.在我的例子中,我使用了一个预先存在的sqlite3数据库.

在" class Users(Base)" 行中,您需要使用MySQL数据库中的一个现有表.我知道我的sqlite3数据库有一个名为"users"的表.

在此之后,SQLalchemy知道如何连接到MySQL数据库,并且知道其中一个表.您现在需要添加您关心的所有其他表.最后,您需要指定与SQLalchemy的关系.在这里,我指的是像一对一,一对多,多对多,亲子等等.SQLAlchemy网站包含一个相当长的部分.

在行" if __name__ == '__main__'"之后只是出现了一些测试代码.如果我不导入我的python脚本,它将被执行,但运行.在这里,您可以看到我创建了一个数据库会话,这是一个非常简单的查询.

我的建议是你首先阅读SQLAlchemy文档的重要部分,例如描述性表定义,关系模型以及如何查询.一旦你知道这一点,你可以将我的示例的最后一部分更改为控制器(例如使用Python的yield方法)并编写一个使用该控制器的视图.


xys*_*sun 54

将Holger的答案与瓶子上下文联系起来的关键是这样db.Modeldeclarative_base对象Base.我花了一些时间在flask-sqlalchemy的文档中注意到这个重要的句子

以下是我用于我的应用的步骤:

  1. db以通常的烧瓶 - 炼金术方式启动一个物体:db = SQLAlchemy(app).请注意,您需要在此app.config['SQLALCHEMY_DATABASE_URI'] = 'connection_string'之前设置.

  2. 将声明性基础绑定到引擎: db.Model.metadata.reflect(db.engine)

  3. 然后您可以轻松使用现有表格(例如,我有一个名为BUILDINGS的表格):

    class Buildings(db.Model):
        __table__ = db.Model.metadata.tables['BUILDING']
    
        def __repr__(self):
            return self.DISTRICT
    
    Run Code Online (Sandbox Code Playgroud)

现在,您的Buildings类将遵循现有架构.您可以dir(Buildings)在Python shell中尝试并查看已列出的所有列.

  • 关于“ db.Model是像Base这样的declarative_base对象”的见解使我大吃一惊。在我读到这篇文章之前,我还不知道要在烧瓶炼金术中做到这一点。谢谢。 (4认同)
  • 当谈到Flask-sqlalchemy db.Model时,类似于Base。db.session与会话类似。 (3认同)

Chr*_*nel 19

我最近经历了同样的事情,还有将这些模型链接到两个数据库的额外挑战.

我使用了Flask-SQLAlchemy,我所要做的就是以与我的数据库表相同的方式定义我的模型,我就笑了.我发现很难找到我的项目结构应该是什么样子.

我的项目是一个Restful API,这就是我最终的结果:

conf/
    __init__.py
    local.py
    dev.py
    stage.py
    live.py
deploy/
    #nginx, uwsgi config, etc
middleware/
    authentication.py
app_name/
    blueprints/
        __init__.py
        model_name.py #routes for model_name
        ...
    models/
        __init.py
        model_name.py
    __init__.py
    database.py
tests/
    unit/
        test_etc.py
        ...
run.py
Run Code Online (Sandbox Code Playgroud)

文件:

CONF/xxx.py

这就是我们告诉Flask-SQLAlchemy要连接的内容,另外你可以在这里放置任何其他配置项(如日志位置,调试配置等).

SQLALCHEMY_DATABASE_URI = 'mysql://username:password@host:port/db_name'
Run Code Online (Sandbox Code Playgroud)

APP_NAME/___ init___.py

这是我创建应用程序并初始化数据库的地方.此db对象将被导入并在整个应用程序中使用(即,在模型,测试等中).我还设置了我的记录器,初始化我的API和蓝图,并在此处附加我的中间件(未显示).

from app_name.database import db
from flask import Flask

def create_app(*args, **kwargs):
    env = kwargs['env']
    app = Flask(__name__)
    app.config.from_object('conf.%s' % env)
    db.init_app(app)
    return app
Run Code Online (Sandbox Code Playgroud)

APP_NAME/database.py

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
Run Code Online (Sandbox Code Playgroud)

APP_NAME /模型/ model_name.py

from services.database import db


class Bar(db.Model):

    __tablename__ = 'your_MySQL_table_name'

    id = db.Column('YourMySQLColumnName', db.Integer, primary_key=True)
    name = db.Column('WhateverName', db.String(100))
    foo = db.Column(db.ForeignKey('another_MySQLTableName.id'))

class Foo(db.Model):

    __tablename__ = 'another_MySQLTableName'

    id = db.Column('FooId', db.Integer, primary_key=True)
    ...
Run Code Online (Sandbox Code Playgroud)

run.py

#! /usr/bin/env python

from app_name import create_app

app = create_app(env='local')

if __name__ == '__main__':
    app.run()
Run Code Online (Sandbox Code Playgroud)

run.py用来在本地运行应用程序,但我使用nginx + uWSGI在dev/stage/live环境中运行应用程序.

我猜你views/除了这个之外还有一个目录.


小智 10

我认为使用sqlalchemy的现有数据库的最简单方法是使用AutomapBase类.docs的示例代码如下:

from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session
from sqlalchemy import create_engine

Base = automap_base()

# engine, suppose it has two tables 'user' and 'address' set up
engine = create_engine("sqlite:///mydatabase.db")

# reflect the tables
Base.prepare(engine, reflect=True)

# mapped classes are now created with names by default
# matching that of the table name.
User = Base.classes.user
Address = Base.classes.address

session = Session(engine)

# rudimentary relationships are produced
session.add(Address(email_address="foo@bar.com", user=User(name="foo")))
session.commit()

# collection-based relationships are by default named
# "<classname>_collection"
print (u1.address_collection)
Run Code Online (Sandbox Code Playgroud)

有关详细信息和更复杂的用法,请参阅SqlAlchemy-Automap


mco*_*lak 5

我尝试使用自动生成,但没有任何效果,或者我无法运行它。当我使用 sqlacodegen 搜索生成代码时,我发现https://github.com/ksindi/flask-sqlacodegen,您可以生成代码

flask-sqlacodegen  mysql://username:password@host:port/db_name --schema yourschema --tables table1,table2 --flask
Run Code Online (Sandbox Code Playgroud)

我试过了,效果很好