我使用SQLAlchemy使用public sealed class Project
{
public int Id {get; private set}
public static Project Instance { get; private set; }
public string Directory { get; private set; }
public string Name { get; private set;
public void Write()
{
using (var context = new DataContext(new System.Data.SQLite.SQLiteConnection(dbPath), false)
{
context.Projects.Add(this);
context.SaveChanges(); //when only Project is included in my database this works great, but an exception is thrown here whenever I include other classes.
}
}
}
动态生成PL / SQL并设置public abstract class FunctionBase
{
public int Id { get; private set; }
public abstract bool IsValid {get; protected set; }
public void Write()
{
using (var context = new DataContext(new System.Data.SQLite.SQLiteConnection(dbPath), false)
{
context.Functions.Add(this);
context.SaveChanges();
}
}
}
public sealed OrdinatesFunction: FunctionBase
{
public override bool IsValid {get; protected set;}
public Statistics.CurveIncreasing Function {get; private set}
}
public abstract Decorator: FunctionBase
{
public virtual FunctionBase Function { get; set; } //this is a required navigation property I think.
public override bool IsValid { get; protected set; }
}
public sealed OutflowFrequencyDecorator: Decorator
{
public override bool IsValid { get; protected set; }
}
和public class DataContext: DbContext
{
public DbSet<Projects>
public DbSet<FunctionBase> Functions { get; set; }
public DbSet<OutflowFrequencyDecorator> { get; set; } //I've tried it with and without this and if fails the same way in both instances.
public DataContext(DbConnection connection, bool contextOwnsConnection): base(connection, contextOwnsConnection)
{
}
public override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Project>();
modelBuilder.Entity<FunctionBase>();
modelBuilder.Entity<OutflowFrequencyDecorator>().HasRequired(t=> t.Function);
var sqLiteConnectionInitializer = new SQLite.CodeFirst.SqLiteCreateDatabaseIfNotExists<DataContext>(modelBuilder);
SetInitializer(sqLiteConnectionInitializer);
}
}
参数(例如,使用compile
)工作正常,除了输出没有在最漂亮的SQL语句中格式化。
例如,我的一个输出看起来像这样:
dialect
相反,我希望打印出来如下:
compile_kwargs
如何让SQLAlchemy打印出漂亮的SQL语句?
要复制:
from sqlalchemy import table, column, String, Numeric, func, select from sqlalchemy.dialects import oracle my_table = table('my_table', column('a', String), column('b', String), column('c', String)) my_table2 = table('my_table2', column('d', String), column('g', String)) my_table3 = table('my_table3', column('d', String), column('e', String), column('f', Numeric), column('g', String), column('h', String)) inner_sel = select([my_table3.c.e, func.max(my_table3.c.f).label('f'), func.count(my_table3.c.g).label('g')]).where(my_table3.c.h=='foo').group_by(my_table3.c.e).having(func.count(my_table3.c.g)==1).alias('bar') outer_sel = select([my_table2.c.d, inner_sel.c.e, inner_sel.c.f]).select_from(my_table2.join(inner_sel, my_table2.c.g==inner_sel.c.g)) ins = my_table.insert().from_select([my_table.c.a, my_table.c.b, my_table.c.c], outer_sel) print ins.compile(dialect=oracle.dialect(), compile_kwargs={'literal_binds': True})
答案 0 :(得分:3)
你可以使用sqlparse包,sqlparse.format(sql, reindent=True, keyword_case='upper')
应该做你想做的事吗?
答案 1 :(得分:3)
有几种选择:
答案 2 :(得分:1)
项目sqlparse
已经成熟(超过10年),并且仍然非常活跃。 sqlparse
旨在解析,拆分和格式化SQL语句。
以下示例使用sqlparse
对SQL文件进行漂亮的格式化:
import argparse
import sqlparse
# Parse command line arguments
parser = argparse.ArgumentParser(prog="pretty_print_sql")
parser.add_argument("file", type=argparse.FileType("r"), nargs="+")
args = parser.parse_args()
# Pretty print input files
for file in args.file:
print(sqlparse.format(file.read(), reindent=True, keyword_case='upper'))
要使用sqlparse
来安装pip
供个人使用:
python3 -m pip install sqlparse --user --upgrade
要使用sqlparse
(在项目内)安装pipenv
:
python3 -m pipenv install sqlparse
答案 3 :(得分:0)
在@v_retoux和@olibre的示例之后,我在使用GitHub的sqlparse上创建了易于部署的脚本。它处理一个或多个sql文件,并具有干净的输出,可以将其通过管道传输给单个文件。
以下是来源:
import argparse, sqlparse, re
parser = argparse.ArgumentParser(prog="sqlpp")
parser.add_argument("--verbose", "-v", action='store_true')
parser.add_argument("file", type=argparse.FileType("r"), nargs="+")
args = parser.parse_args()
def prepend(s, s2): return s2 + re.sub('\n', '\n'+s2, s)
# Pretty print input files
n=len(args.file)
for i, file in enumerate(args.file):
sIn = file.read().replace('\n', '')
file.close()
sOut = sqlparse.format(sIn, reindent=True, keyword_case='upper')
if args.verbose or n > 1:
print("File{0}:\n {1}\n{2}\nFormatted SQL:\n{3}\n".format(
(' ' + str(i+1) if n > 1 else '')
,file.name
,("\nOriginal SQL:\n{}\n".format(prepend(sIn, " "))
if args.verbose else "")
,prepend(sOut, " ")
))
else:
print(sOut)
答案 4 :(得分:0)
试试这个猴子补丁:
pip install sqlparse
### monkeypatching SQL'Alchemy for pretty SQL query printing (((
from sqlalchemy.log import InstanceLogger
def pretty_log(self, level, msg, *args, **kwargs):
if self.logger.manager.disable >= level:
return
selected_level = self._echo_map[self.echo]
if selected_level == logging.NOTSET:
selected_level = self.logger.getEffectiveLevel()
if level >= selected_level:
import sqlparse
### HERE IT IS ###
msg = sqlparse.format(msg, reindent=True, keyword_case='upper')
self.logger._log(level, '\n'+msg, args, **kwargs)
InstanceLogger.log = pretty_log
### )))