SQLAlchemy drukowanie surowego SQL z create()

Daję Pylons spróbować z SQLAlchemy, i kocham to, jest tylko jedna rzecz, jest możliwe, aby wydrukować surowe dane SQL CREATE TABLE wygenerowane z Table ().create () przed wykonaniem?

Author: Mads Madsen, 2010-01-24

7 answers

from sqlalchemy.schema import CreateTable

print(CreateTable(table))

Jeśli używasz składni deklaratywnej:

print(CreateTable(Model.__table__))

Update:

Ponieważ mam zaakceptowaną odpowiedź i jest ważna informacja w odpowiedź klenwella, dodam ją również tutaj.

Możesz uzyskać SQL dla konkretnej bazy danych (MySQL, Postgresql, itp.) poprzez kompilację z silnikiem.

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

Aktualizacja 2:

@Jackotonye dodał w komentarzach sposób zrobić to bez silnika.
print(CreateTable(Model.__table__).compile(dialect=postgresq‌​l.dialect()))
 72
Author: Antoine Leclair,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:23

Musiałem pobrać surową tabelę sql, aby skonfigurować testy dla niektórych istniejących modeli. Oto udany test jednostkowy, który stworzyłem dla SQLAlchemy 0.7.4 na podstawie odpowiedzi Antoine ' a jako dowód koncepcji:

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))
 11
Author: klenwell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:59
 8
Author: Tefnet Developers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-10 16:57:56

Możesz skonfigurować you engine do zrzutu sekwencji tworzenia metadanych, używając następujących opcji:

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)

Jedną z zalet tego podejścia jest to, że w wydruku znajdują się wyliczenia i indeksy. Użycie CreateTable zostawia to.

Kolejną zaletą jest to, że kolejność definicji schematu jest poprawna i (prawie) użyteczna jako skrypt.

 6
Author: Lars,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-10 14:42:26

Może masz na myśli echo parametr sqlalchemy.create_engine?

/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

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
 1
Author: xni,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-24 12:14:54

Okazuje się, że jest to proste:

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()))

Wypisuje to:

CREATE TABLE users (
    username VARCHAR
)

Idąc dalej, może nawet obsługiwać powiązane parametry w przygotowanych instrukcjach.

Odniesienie

Jak renderować wyrażenia SQL jako ciągi znaków, ewentualnie z wewnętrznymi parametrami?

...

Lub bez silnika:

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

Źródło: http://docs.sqlalchemy.org/en/latest/faq/sqlexpressions.html#faq-sql-expression-string

Przykład: użycie SQL Alchemy do generowania skryptu zmiany nazwy użytkownika

#!/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})) + ';')

Podczas przetwarzania tego użytkownika.csv:

sAMAccountName,mail
bmcboatface,[email protected]
ndhyani,[email protected]

Daje wynik w ten sposób:

UPDATE users SET username='[email protected]' WHERE users.username = 'bmcboatface';
UPDATE users SET username='[email protected]' WHERE users.username = 'ndhyani';users.username = 'ndhyani';

Dlaczego statek badawczy ma adres e-mail nie jest jeszcze ustalona. Byłem w kontakcie z zespołem IT firmy Example Inc i nie otrzymałem odpowiedzi.

 1
Author: Alain O'Dea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-13 03:59:35

SQLAlchemy jest zaprojektowany w taki sposób, że nie pozwala na odtwarzanie wygenerowanych instrukcji DDL bez ich rzeczywistego wykonania. AFAIK, SQLAlchemy Migrate Użyj mock engine do przechwytywania instrukcji bez wykonywania, gdy używana jest opcja --preview_sql, więc użycie jej jest jednym ze sposobów rozwiązania problemu.

 -2
Author: Denis Otkidach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-25 10:56:47