knex.js - debug only SQL - express

Is there any way to display only SQL queries on console when debugging mode is on?
I want to reduce the amount of informations which is displayed.
Thanks for the help ;)

Set environment variables to configure the debug module:
DEBUG=knex:query for just queries
DEBUG=knex:tx for transactions
and DEBUG=knex* for everything.

If what you need is to show the query string, one way is to register a function that logs the query data using the event 'query' that Knex emit just before executing the query.
For example:
var knex = require( 'knex' );
knex.on( 'query', function( queryData ) {
console.log( queryData );
});
After that, before every query, the anonymous function is called and queryData contains json with the information about the query.

Actually, if you're using MySQL, you can set
debug: ['ComQueryPacket']
as part of the config settings for mysql (not Knex).
I'll looking into adding this as an option in Knex though.

Related

Return inserted id with TypeORM & NestJS raw query: await connection.manager.query(`INSERT INTO

I'm looking to return the id or better yet, all information that was inserted, using a raw query with TypeORM and NestJS. Example as follows:
await connection.manager.query(`INSERT INTO...`)
When assigning the query to a constant and console logging it below, it does not yield any helpful information:
OkPacket {
fieldCount: 0,
affectedRows: 1,
insertId: 0,
serverStatus: 2,
warningCount: 1,
message: '',
protocol41: true,
changedRows: 0
}
As you can see, it returns no pertinent information, the insertId above is obviously incorrect, and it returns this every time, regardless of the actual parameters of the query.
I know with more typical TypeORM queries you can use .return(['name_of_column_you_want_returned']).execute()
and it will return the relevant information just fine. Is there any way to do this with a raw query? Thank you!
tl;dr You're getting the raw mariadb driver response (OkPacket) from the INSERT command, and you'd need a new SELECT query to see the data.
You're using the TypeORM EntityManager, and the docs don't mention a return value. Looking at the source code for query, the return type is any. Since it's a raw query, it probably returns an object based on the type of database you're using rather than having a standard format.
In this case, you're using MariaDb, which returned an OkPacket. Here's the documentation:
https://mariadb.com/kb/en/ok_packet/

Laravel: toSql function not displaying query correctly

I am trying to diedump the query on my index screen using this line of code:
dd(DB::table('members')->where('name', '=', 'Tycho')->toSql());
Now the problem is that when I am displaying the query on my screen I get this:
"select * from `members` where `name` = ?"
My final goal of these lines of code is that I can save offline queries and execute them when the application is online. Unless someone has a solution for this, I'll have to save the queries in a database.
You are seeing the ? placeholders as Laravel uses Prepared Statements.
See Ijas Ameenudeen's answer on another SO question which details how to add a toRawSql() macro on the Eloquent builder which will replace the placeholders with the bindings that you supplied to the original query.
This is because you are using the toSql method, you can use the getBindings method to get the values / bindings.
oneliner:
$query = DB::table('members')->where('name', '=', 'Tycho')->toSql();
// will give the raw query with bindings.
$sqlWithBindings = str_replace_array('?', $query->getBindings(), $query->toSql());
You can try this:
DB::enableQueryLog();
DB::table('members')->where('name', '=', 'Tycho')->get();
echo "<pre>";
print_r(DB::getQueryLog());

RavenDB DeleteByIndex RetrieveDetails

I have a RavenDB Index that I am using to delete a bunch of documents at one time. I would like to know home many documents were actually deleted after the operation is done, however I can't figure out how to get that information from a DatabaseCommands call. For a RavenQuery/DocumentQuery you can use the out Statistics, but I haven't found anything for the DatabaseCommands.
I did find a RetrieveDetails flag as part of the BulkOperationsOptions but I'm not sure how to actually see the details. Here is what my query looks like
var op = connection.Store.DatabaseCommands.DeleteByIndex(
"Store/ByExpiration",
new IndexQuery
{
Query = "Expiration:yes"
},
new BulkOperationOptions
{
AllowStale = false,
RetrieveDetails = true
});
op.WaitForCompletion();
At this point I am not sure how to get the details once the operation has completed. Has anyone else figured out how to get these details?
The result is returned as a RavenJToken in WaitForCompletion.
var result = op.WaitForCompletion();
The documentation isn't clear on this.
Hint: When I can't find examples in the documentation I look at the RavenDB source code unit tests for examples, e.g. the ShouldRetrieveOperationDetailsWhenTheyWereRequested unit test.

Can I pretty-print the DBIC_TRACE output in DBIx::Class?

Setting the DBIC_TRACE environment variable to true:
BEGIN { $ENV{DBIC_TRACE} = 1 }
generates very helpful output, especially showing the SQL query that is being executed, but the SQL query is all on one line.
Is there a way to push it through some kinda "sql tidy" routine to format it better, perhaps breaking it up over multiple lines? Failing that, could anyone give me a nudge into where in the code I'd need to hack to add such a hook? And what the best tool is to accept a badly formatted SQL query and push out a nicely formatted one?
"nice formatting" in this context simply means better than "all on one line". I'm not particularly fussed about specific styles of formatting queries
Thanks!
As of DBIx::Class 0.08124 it's built in.
Just set $ENV{DBIC_TRACE_PROFILE} to console or console_monochrome.
From the documentation of DBIx::Class::Storage
If DBIC_TRACE is set then trace information is produced (as when the
debug method is set). ...
debug Causes trace information to be emitted on the debugobj
object. (or STDERR if debugobj has not specifically been set).
debugobj Sets or retrieves the object used for metric collection.
Defaults to an instance of DBIx::Class::Storage::Statistics that is
compatible with the original method of using a coderef as a callback.
See the aforementioned Statistics class for more information.
In other words, you should set debugobj in that class to an object that subclasses DBIx::Class::Storage::Statistics. In your subclass, you can reformat the query the way you want it to be.
First, thanks for the pointers! Partial answer follows ....
What I've got so far ... first some scaffolding:
# Connect to our db through DBIx::Class
my $schema = My::Schema->connect('dbi:SQLite:/home/me/accounts.db');
# See also BEGIN { $ENV{DBIC_TRACE} = 1 }
$schema->storage->debug(1);
# Create an instance of our subclassed (see below)
# DBIx::Class::Storage::Statistics class
my $stats = My::DBIx::Class::Storage::Statistics->new();
# Set the debugobj object on our schema's storage
$schema->storage->debugobj($stats);
And the definition of My::DBIx::Class::Storage::Statistics being:
package My::DBIx::Class::Storage::Statistics;
use base qw<DBIx::Class::Storage::Statistics>;
use Data::Dumper qw<Dumper>;
use SQL::Statement;
use SQL::Parser;
sub query_start {
my ($self, $sql_query, #params) = #_;
print "The original sql query is\n$sql_query\n\n";
my $parser = SQL::Parser->new();
my $stmt = SQL::Statement->new($sql_query, $parser);
#printf "%s\n", $stmt->command;
print "The parameters for this query are:";
print Dumper \#params;
}
Which solves the problem about how to hook in to get the SQL query for me to "pretty-ify".
Then I run a query:
my $rs = $schema->resultset('SomeTable')->search(
{
'email' => $email,
'others.some_col' => 1,
},
{ join => 'others' }
);
$rs->count;
However SQL::Parser barfs on the SQL generated by DBIx::Class:
The original sql query is
SELECT COUNT( * ) FROM some_table me LEFT JOIN others other_table ON ( others.some_col_id = me.id ) WHERE ( others.some_col_id = ? AND email = ? )
SQL ERROR: Bad table or column name '(others' has chars not alphanumeric or underscore!
SQL ERROR: No equijoin condition in WHERE or ON clause
So ... is there a better parser than SQL::Parser for the job?

SQL server profiler not showing LINQ To Sql queries

I am trying to view SQL generated by Linq to SQL in the SQL Server Profiler (2005).
I can see the sql sent to the server from anything except for linq to sql.
I'm betting that I need to change event selections for the trace, but not sure what else to select.
I am currently only selecting this:
SQL:StmtCompleted - TextData & SPID
I don't want to use data context logging nor the SQL Debug Visualizer. I need to use the profiler.
Why can I not see the LINQ to SQL queries?
Thanks.
EDIT
I added SQL:BatchCompleted and that hasn't helped.
EDIT 2
I added the event RPC:Completed which is found under the Stored Procedures category in event selection. This worked!
You need RPC call - the queries are executed as exec_sql.
Are you including enough of the options in the SQL Profiler to see the BatchCompleted events, too?
Marc
There is also an option in the data context class to enable log in the client side. When log is enabled is possible to see the queries.
See this link:
http://www.davidhayden.com/blog/dave/archive/2007/08/17/DataContextLogLoggingLINQToSQLOutputConsoleDebuggerOuputWindow.aspx
Had the same problem and none of the solutions above worked for me.
What worked for me was adding ToList() enumerator to the query.
Before:
var data = null == id ?
(from ...
select new
{
...
})
:
(from ..
select new
{
...
});
After:
var data = null == id ?
(from ...
select new
{
...
}).ToList()
:
(from ..
select new
{
...
}).ToList();
foreach (var obj in data)
{
xxx = obj.somename; --> now you can see the sql query in Profiler