Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何围绕现有数据库构建flask应用程序?_Python_Mysql_Sqlalchemy_Flask_Flask Sqlalchemy - Fatal编程技术网

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

Python 如何围绕现有数据库构建flask应用程序?,python,mysql,sqlalchemy,flask,flask-sqlalchemy,Python,Mysql,Sqlalchemy,Flask,Flask Sqlalchemy,我已经有了一个现有的数据库,在MySQL中有很多表和很多数据。我打算创建一个Flask应用程序,并使用sqlalchemy。现在我在irc上发问,在谷歌上四处看看,并尝试了以下想法: 首先我使用我的DB生成模型。但后来我有点困惑,又看了看。我发现了 这看起来是一个优雅的解决方案 因此,第二次,我根据那里的解决方案重写了我的models.py,现在我更加困惑了。我正在寻找最好的方法来构建这个flask应用程序以及已经存在的DB 我查阅了flask文档,但是对于一个已经存在db的项目,我并没有得到任

我已经有了一个现有的数据库,在
MySQL
中有很多表和很多数据。我打算创建一个
Flask
应用程序,并使用sqlalchemy。现在我在irc上发问,在谷歌上四处看看,并尝试了以下想法:

首先我使用我的
DB
生成模型。但后来我有点困惑,又看了看。我发现了

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

因此,第二次,我根据那里的解决方案重写了我的
models.py
,现在我更加困惑了。我正在寻找最好的方法来构建这个flask应用程序以及已经存在的DB

我查阅了flask文档,但是对于一个已经存在db的项目,我并没有得到任何帮助。有很多好东西可以从头开始创建,创建数据库等等。但我真的很困惑


请注意,这是我第一天使用
Flask
,但我有使用
Django
的经验,因此基本概念不是障碍。在为这个用例选择最佳方法时,我需要一些指导。如能详细解释,将不胜感激。通过详细说明,我绝对不希望有人编写所有的代码并用勺子喂我,但这足以让我开始,那就是通过
sqlalchemy
将此db无缝集成到
flask
。注意我的数据库在MySQL中,我想说你的问题与flask没有任何关系。例如,模板、路由、视图或登录装饰器并没有问题

你挣扎的地方是炼金术

所以我的建议是暂时忽略烧瓶,先习惯炼金术。您需要习惯现有数据库以及如何从SQLAlchemy访问它。使用一些MySQL文档工具来解决这个问题。开始时是这样的(请注意,它与烧瓶问所有……还没有任何关系):

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

在“
classusers(Base)
”行中,您需要使用MySQL数据库中的一个现有表。我知道我的sqlite3数据库有一个名为“users”的表

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

在“
行后面,如果
”后面是一些测试代码。如果我不导入python脚本,而是运行。在这里,您可以看到我创建了一个DB会话,这是一个非常简单的查询


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

我最近经历了同样的事情,还有一个额外的挑战是跨两个数据库链接模型

我使用了,我所要做的就是以与数据库表相同的方式定义模型。我发现困难的是弄清楚我的项目结构应该是什么样子

我的项目是一个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
值得注意的文件:

conf/xxx.py

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
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)
    ...
#! /usr/bin/env python

from app_name import create_app

app = create_app(env='local')

if __name__ == '__main__':
    app.run()
这就是我们告诉Flask SQLAlchemy连接到什么的方式,另外您可以在这里放置任何其他配置项(如日志位置、调试配置等)

app\u name/\uuuuuu init\uuuuuuuuuuuuuuuuuupy

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
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)
    ...
#! /usr/bin/env python

from app_name import create_app

app = create_app(env='local')

if __name__ == '__main__':
    app.run()
这是我创建应用程序并初始化db的地方。此db对象将导入并在整个应用程序中使用(即,在模型、测试等中)。我还设置了我的记录器,初始化了我的API和蓝图,并将我的中间件连接到这里(未显示)

app\u name/database.py

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
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)
    ...
#! /usr/bin/env python

from app_name import create_app

app = create_app(env='local')

if __name__ == '__main__':
    app.run()
app\u name/models/model\u name.py

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
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)
    ...
#! /usr/bin/env python

from app_name import create_app

app = create_app(env='local')

if __name__ == '__main__':
    app.run()
run.py

from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
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)
    ...
#! /usr/bin/env python

from app_name import create_app

app = create_app(env='local')

if __name__ == '__main__':
    app.run()
我使用
run.py
在本地运行应用程序,但我使用nginx+uWSGI在dev/stage/live环境中运行应用程序


我猜除此之外,还有一个
views/
目录。

将霍尔格的答案连接到烧瓶上下文的关键是
db.Model
是一个
声明性的\u base
对象,类似于
base
。我花了一段时间才注意到炼金术中这句重要的话

以下是我在应用程序中使用的步骤:

  • 以普通烧瓶炼金术方式启动
    db
    对象:
    db=SQLAlchemy(app)
    。注意,在此之前,您需要设置app.config['SQLALCHEMY\u DATABASE\u URI']='connection\u string'

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

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


  • 现在,您的
    Buildings
    类将遵循现有模式。您可以在Python shell中尝试
    dir(Buildings)
    ,查看已经列出的所有列

    这是另一种设置霍尔格回答中描述的发动机路径的方法。如果用户名或密码中有特殊字符,则很方便

    from sqlalchemy.engine.url import URL
    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    
    engine_URL = URL('mssql+pymssql',
                     username='DOMAIN\\USERNAME', 
                     password="""p@ssword'!""", 
                     host='host.com', 
                     database='database_name')
    
    engine = create_engine(engine_URL)
    Base = declarative_base()
    Base.metadata.reflect(engine)
    

    我认为通过sqlalchemy使用现有数据库最简单的方法是使用类。文档中的示例代码如下所示:

    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)
    
    从sqlalchemy.ext.automap导入automap\u base
    从sqlalchemy.orm导入会话
    来自sqlalch