简体   繁体   English

SQLAlchemy 从 create() 打印原始 SQL

[英]SQLAlchemy printing raw SQL from create()

我正在使用 SQLAlchemy 尝试 Pylons,我喜欢它,只有一件事,是否可以在执行之前打印出从Table().create()生成的原始 SQL CREATE TABLE数据?

from sqlalchemy.schema import CreateTable

print(CreateTable(table))

If you are using declarative syntax:如果您使用声明式语法:

print(CreateTable(Model.__table__))

Update:更新:

Since I have the accepted answer and there is important information in klenwell answer , I'll also add it here.由于我已经接受了答案并且klenwell answer 中有重要信息,我也会在这里添加它。

You can get the SQL for your specific database (MySQL, Postgresql, etc.) by compiling with your engine.您可以通过使用引擎进行编译来获取特定数据库(MySQL、Postgresql 等)的 SQL。

print(CreateTable(Model.__table__).compile(engine))

Update 2:更新 2:

@jackotonye Added in the comments a way to do it without an engine. @jackotonye 在评论中添加了一种无需引擎的方法。

print(CreateTable(Model.__table__).compile(dialect=postgresql.dialect()))

I needed to get the raw table sql in order to setup tests for some existing models.我需要获取原始表 sql 以便为某些现有模型设置测试。 Here's a successful unit test that I created for SQLAlchemy 0.7.4 based on Antoine's answer as proof of concept:这是我基于Antoine 的答案为 Sqlalchemy 0.7.4 创建的一个成功的单元测试作为概念证明:

from sqlalchemy import create_engine
from sqlalchemy.schema import CreateTable
from model import Foo

sql_url = "sqlite:///:memory:"    
db_engine = create_engine(sql_url)

table_sql = CreateTable(Foo.table).compile(db_engine)
self.assertTrue("CREATE TABLE foos" in str(table_sql))

You can set up you engine to dump the metadata creation sequence, using the following:您可以使用以下命令设置引擎以转储元数据创建序列:

def metadata_dump(sql, *multiparams, **params):
    # print or write to log or file etc
    print(sql.compile(dialect=engine.dialect))

engine = create_engine(myDatabaseURL, strategy='mock', executor=metadata_dump)
metadata.create_all(engine)

One advantage of this approach is that enums and indexes are included in the printout.这种方法的一个优点是枚举和索引包含在打印输出中。 Using CreateTable leaves this out.使用CreateTable这一点。

Another advantage is that the order of the schema definitions is correct and (almost) usable as a script.另一个优点是模式定义的顺序是正确的并且(几乎)可用作脚本。

Something like this?像这样的东西? (from the SQLA FAQ) (来自 SQLA 常见问题解答)

http://docs.sqlalchemy.org/en/latest/faq/sqlexpressions.htmlhttp://docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html

It turns out this is straight-forward:事实证明这是直截了当的:

from sqlalchemy.dialects import postgresql
from sqlalchemy.schema import CreateTable
from sqlalchemy import Table, Column, String, MetaData

metadata = MetaData()

users = Table('users', metadata,
              Column('username', String)
)

statement = CreateTable(users)

print(statement.compile(dialect=postgresql.dialect()))

Outputs this:输出这个:

CREATE TABLE users (
    username VARCHAR
)

Going further, it can even support bound parameters in prepared statements.更进一步,它甚至可以支持准备好的语句中的绑定参数。

Reference参考

How do I render SQL expressions as strings, possibly with bound parameters inlined?如何将 SQL 表达式呈现为字符串,可能带有内联的绑定参数?

... ...

or without an Engine:或没有引擎:

 from sqlalchemy.dialects import postgresql print(statement.compile(dialect=postgresql.dialect()))

SOURCE: http://docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html#faq-sql-expression-string来源: http : //docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html#faq-sql-expression-string

Example: Using SQL Alchemy to generate a user rename script示例:使用 SQL Alchemy 生成用户重命名脚本

#!/usr/bin/env python
import csv
from sqlalchemy.dialects import postgresql
from sqlalchemy import bindparam, Table, Column, String, MetaData

metadata = MetaData()

users = Table('users', metadata,
              Column('username', String)
)

renames = []

with open('users.csv') as csvfile:
    for row in csv.DictReader(csvfile):
        renames.append({
            'from': row['sAMAccountName'],
            'to': row['mail']
        })

for rename in renames:
    stmt = (users.update()
            .where(users.c.username == rename['from'])
            .values(username=rename['to']))
    print(str(stmt.compile(dialect=postgresql.dialect(),
                           compile_kwargs={"literal_binds": True})) + ';')

When processing this users.csv:处理此 users.csv 时:

sAMAccountName,mail
bmcboatface,boaty.mcboatface@example.com
ndhyani,naina.dhyani@contoso.com

Gives output like this:给出这样的输出:

UPDATE users SET username='boaty.mcboatface@example.com' WHERE users.username = 'bmcboatface';
UPDATE users SET username='naina.dhyani@contoso.com' WHERE users.username = 'ndhyani';users.username = 'ndhyani';

Why a research vessel has an email address is yet to be determined.为什么研究船有电子邮件地址尚待确定。 I have been in touch with Example Inc's IT team and have had no response.我已与 Example Inc 的 IT 团队取得联系,但没有任何回应。

May be you mean echo parameter of sqlalchemy.create_engine?可能你的意思是 sqlalchemy.create_engine 的echo参数?

/tmp$ cat test_s.py /tmp$ cat test_s.py

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Department(Base):
    __tablename__ = "departments"

    department_id = sa.Column(sa.types.Integer, primary_key=True)
    name = sa.Column(sa.types.Unicode(100), unique=True)
    chief_id = sa.Column(sa.types.Integer)
    parent_department_id = sa.Column(sa.types.Integer,
                                     sa.ForeignKey("departments.department_id"))

    parent_department = sa.orm.relation("Department")


engine = sa.create_engine("sqlite:///:memory:", echo=True)
Base.metadata.create_all(bind=engine)

/tmp$ python test_s.py /tmp$ python test_s.py

2011-03-24 15:09:58,311 INFO sqlalchemy.engine.base.Engine.0x...42cc PRAGMA table_info("departments")
2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc ()
2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc 
CREATE TABLE departments (
    department_id INTEGER NOT NULL, 
    name VARCHAR(100), 
    chief_id INTEGER, 
    parent_department_id INTEGER, 
    PRIMARY KEY (department_id), 
    UNIQUE (name), 
    FOREIGN KEY(parent_department_id) REFERENCES departments (department_id)
)

2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc ()
2011-03-24 15:09:58,312 INFO sqlalchemy.engine.base.Engine.0x...42cc COMMIT

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM