架构和列之间有什么区别?

时间:2017-08-22 15:53:27

标签: python postgresql sqlalchemy

这可能是一个天真的问题,我正在教自己Postgresql和sqlalchemy,

在此示例中为

https://groups.google.com/forum/#!topic/sqlalchemy/p6U-pzZe6II

     from sqlalchemy import schema

     from sqlalchemy import types
     moment = schema.Column(types.Time(timezone=True))

但是我一直在学习

    from sqlalchemy import DateTime
    app = Flask(__name__)
    db = SQLAchemy(app)
    visitor_time = db.Column(DateTime(timezone=True))

那么这两者之间有什么区别?

1 个答案:

答案 0 :(得分:0)

好吧,你使用的是两个不同的软件包:SQLAlchemy(第一种情况)和Flask-SQLAlchemy(第二种情况)。 Flask-SQLAlchemy是SQLAlchemy的一种扩展,正如它所说的

  

它的目的是通过提供有用的默认值和额外的帮助程序来简化将SQLAlchemy与Flask结合使用,从而更轻松地完成常见任务。

好的,让我们从如何开始使用数据库开始。对于大多数数据库,从上到下的逻辑层次结构为cluster->database(catalog)->schema->table->column,请检查Catalog,以及每个级别的官方定义。前三个级别(群集,数据库和架构)通常由数据库管理员完成。数据库管理员应该设置集群,并为您创建数据库和用户。然后,您可以使用客户端登录数据库(例如,psql用于PostgreSQL)。完成这些步骤后,将为您分配一个包含访问信息的数据库(主机,数据库,用户名,密码等)。这些是连接数据库(SQLAlchemy create_engine

的必要信息

我们不使用SQLAlchemy来执行上述三个步骤。相反,我们使用SQLAlchemy定义下级(TablesColumns)并获得ORM的好处。这称为数据定义语言DDL

现在来看第一种情况,SQLAlchemy提供了一个包sqlalchemy.schema来实现DDL。正如says

  

数据库元数据可以通过使用Table,Column,ForeignKey和Sequence等构造显式命名各种组件及其属性来表达,所有这些都是从sqlalchemy.schema包导入的。

对于您的第二种情况,Flask-SQLAlchemy,SQLAlchemy的自定义版本。他们提供了一个新的类SQLAlchemy,它像包装器一样工作,正如文档所说:

  

此类还提供对sqlalchemy和sqlalchemy.orm模块中所有SQLAlchemy函数和类的访问。

如果您有兴趣,可以查看Flask-SQLAlchemy的源代码。以下是SQLAlchemyFlask-SQLAlchemy类的一些代码段:

class SQLAlchemy(object):
    def __init__(self, app=None, use_native_unicode=True, 
                 session_options=None,
                 metadata=None, query_class=BaseQuery, model_class=Model):

        self.use_native_unicode = use_native_unicode
        self.Query = query_class
        self.session = self.create_scoped_session(session_options)
        self.Model = self.make_declarative_base(model_class, metadata)
        self._engine_lock = Lock()
        self.app = app
        _include_sqlalchemy(self, query_class)


def _include_sqlalchemy(obj, cls):
    for module in sqlalchemy, sqlalchemy.orm:
        for key in module.__all__:
            if not hasattr(obj, key):
                setattr(obj, key, getattr(module, key))
    # Note: obj.Table does not attempt to be a SQLAlchemy Table class.
    obj.Table = _make_table(obj)
    obj.relationship = _wrap_with_default_query_class(obj.relationship, cls)
    obj.relation = _wrap_with_default_query_class(obj.relation, cls)
    obj.dynamic_loader = _wrap_with_default_query_class(obj.dynamic_loader, cls)
    obj.event = event


def _make_table(db):
    def _make_table(*args, **kwargs):
        if len(args) > 1 and isinstance(args[1], db.Column):
            args = (args[0], db.metadata) + args[1:]
        info = kwargs.pop('info', None) or {}
        info.setdefault('bind_key', None)
        kwargs['info'] = info
        return sqlalchemy.Table(*args, **kwargs)
    return _make_table

如您所见,db.Model实际上是DeclarativeBase的一个实例。当您拨打db.Table(这是一个功能)时,它实际上会调用_make_table,最后调用sqlalchemy.Table

希望这会有所帮助。 感谢。