how to use django.core.management.sql.sql_create? - sql

I want to use this function:
django.core.management.sql.sql_create in my view, to get the "CREATE" statements
the function gets 3 arguments:
app, style, connection
what is "app"?? is it a specific object or just the app name?!
I know style is something to do with colors... I reckon django.core.management.color.colorstyle() should work..
what about connection, how do I get this one?
thanks
=========================== edited from here down
ok, after some time, I figured the things, this is what I ended up with:
def sqldumper(model):
"""gets a db model, and returns the SQL statements to build it on another SQL-able db"""
#This is how django inserts a new record
#u'INSERT INTO "polls_poll" ("question", "pub_date") VALUES (GE!!, 2011-05-03 15:45:23.254000)'
result = "BEGIN;\n"
#add CREATE TABLE statements
result+= '\n'.join(sql_create(models.get_app('polls'), color_style(), connections.all()[0]))+"\n"
result+= '\n'.join(sql_custom(models.get_app('polls'), color_style(), connections.all()[0]))+"\n"
result+= '\n'.join(sql_indexes(models.get_app('polls'), color_style(), connections.all()[0]))+"\n"
result+= '\n'
#add INSERT INTO staetements
units = model.objects.all().values()
for unit in units:
statement = "INSERT INTO yourapp.model "+str(tuple(unit.keys()))+" VALUES " + str(tuple(unit.values()))+"\n"
result+=statement
result+="\nCOMMIT;\n"
return result.encode('utf-8')
it's still a bit weird, because you get the CREATE TABLE for the whole app, but the INSERT INTO only for the model you ask.... but it's fixable from here

It's the models.py module found in one of your apps:
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'myproject.myapp',
)
When I printed it, I got < module 'myproject.myapp.models' from '...' >. I used the ellipses instead of typing the entire models.py file's path.

Related

table only record one character of my form field

One of my tables from pgsql has a strange behaviour like the title says.
Here are some screenshots:
As you can see, the name zamdam must be record in the column "nom" in pgadmin instead of recording one letter for one column, here is the sql statement + server code :
await client.queryObject("INSERT INTO users(nom,email,password,adresse,prenom) VALUES($1,$2,$3,$4,$5);",
product.fields.nom,
product.fields.email,
product.fields.password,
product.fields.adresse,
product.fields.prenom
);
let nomFormRegister = product.fields.nom;
console.log(nomFormRegister);
It was working well until I started to add some subtable behaviours between tables, but I deleted all of them and wrote new tables so I don't understand why this issue still appears ...
an other example where i logged in vscode all the fields that should be recorded in my table :
Form :
SQL statement + server code :
console.log :
PgAdmin table - fourth line:
Could you try to run queryArray instead of queryObject for insert operation?
await client.queryArray`INSERT INTO users(nom,email,password,adresse,prenom) VALUES(${product.fields.nom}, ${product.fields.email}, ${product.fields.password}, ${product.fields.adresse}, ${product.fields.prenom}`;
I am not sure if it's gonna work, because I've no deno environment to test it.

QTableView does not retain changes or update after adding records

I am constructing a GUI which displays the contents of a SQL database table and which should allow addition and modification of records through the GUI, using the base PyQt4 classes QTableView and QSqlTableModel. I am having problems with editing the table view.
Here is a Minimal, Complete and Verifiable version of the complete code. It does require changing the login info of whatever SQL database you are using, but besides that the code is sufficient to run the interface:
import sys
import site
from subprocess import Popen
from PyQt4.QtCore import(Qt)
from PyQt4.QtGui import(QMainWindow, QApplication, QWidget, QPushButton, qApp,
QVBoxLayout, QTableView, QApplication)
from PyQt4.QtSql import(QSqlDatabase, QSqlQuery, QSqlQueryModel, QSqlTableModel)
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
# Open and connect to database - this needs to be changed for the particular db you are using
self.__database = QSqlDatabase.addDatabase('QPSQL')
self.__database.setHostName('localhost')
self.__database.setDatabaseName('~/Desktop/H2 testing/TESTING/db/db')
self.__database.setPort(5435)
self.__database.setUserName('grav')
self.__database.setPassword('XXXXXXXXXX')
self.__database.open()
ok = self.__database.open()
if ok == False:
print 'Could not open database'
print 'Text: ', self.__database.lastError().text()
print 'Type: ', str(self.__database.lastError().type())
print 'Number: ', str(self.__database.lastError().number())
print 'Loaded drivers:', str(QSqlDatabase.drivers())
# Create the QSqlTableModel using the database
self.modelDirections = QSqlTableModel(None, self.__database)
self.modelDirections.setTable('PUBLIC.DIRECTIONS')
self.modelDirections.setEditStrategy(QSqlTableModel.OnFieldChange)
self.modelDirections.select()
# Create the QTableView and connect to the QSqlTableModel
self.tableDirections = QTableView()
self.tableDirections.setModel(self.modelDirections)
# Create a QPushButton to add a row to the table
self.buttonAddDir = QPushButton('Add direction')
self.buttonAddDir.clicked.connect(self.createDirection)
# Set up the rest of the window with the QTableView and the QPushButton
vbox = QVBoxLayout()
vbox.addWidget(self.tableDirections)
vbox.addWidget(self.buttonAddDir)
stretchBox = QWidget()
stretchBox.setLayout(vbox)
self.setCentralWidget(stretchBox)
self.show()
def createDirection(self):
# Define and execute query to determine current max direction serial
model = QSqlQueryModel()
query = 'SELECT * FROM directions WHERE id=(SELECT MAX(id) FROM directions)'
model.setQuery(query)
if model.record(0).value('id').toString() == '':
newDirectionSerial = 0
else:
newDirectionSerial = int(model.record(0).value('id').toString()) + 1
# Define queries to insert new direction record
queryText = 'INSERT INTO public.directions (id, text, olddir, opposite) \
VALUES (%s, NULL, 1, NULL)' % (newDirectionSerial)
query = QSqlQuery()
query.exec_(queryText)
if __name__ == "__main__":
app = QApplication(sys.argv)
newWindow = Window()
sys.exit(app.exec_())
On loading the GUI, the table displays correctly in the QTableView. However, I have 2 problems:
I am able to double-click into a field in the table and begin editing, but then when I double-click into another field, anything I entered in the first field disappears.
When I edit a field and then switch to editing a new field, I get the message "Data changed" even though whatever I entered disappears.
My best guess here is that the data is being changed in the QSqlTableModel but then for some reason not translating through to the underlying database field, and when the view refreshes, it does so with an updated model from the still-empty database field.
When I add a new record using the button, the new record doesn't show up. If I close out the script and then start it up again, the new record shows up.
These may well be 2 separate problems but I have a feeling they're related.
I have managed to gather some more information about issue 1 since first posting this problem:
After connecting the QSqlTableModel.dataChanged signal to a reporter function, I'm able to confirm that
The signal is indeed firing when I edit the table-view fields,
The data is not being transferred from the model to the database, because of a problem with the query. The database is returning the following error:
ERROR: Column "text" not found; SQL statement: UPDATE PUBLIC.DIRECTIONS SET "text"='test' WHERE "id" = 1 AND "text" = 'constitutes' AND "dir" = 1 AND "opposite" = 2 [42122-164]
(42S22) QPSQL: Unable to create query
I'm able to access the database through another application and I test-ran variants of this query. Stripping the quotes around the field names and getting rid of the trailing [42122-164] produces a successful query and the behavior I've been looking for.
That's great - but I want the QSqlTableView to handle this, and don't know how. Anyone clues to how to modify the query behavior of the view (without completely rebuilding it) would be immensely appreciated!

passing msqli to a function - can't suss out why it's not working

I've searched high and low for an answer on this, but I'm either missing something, or I just can't find anything in this context.
Background - trying to avoid spaghetti frenzy with a little casual project I'm starting; part of this will involve mainly just calls to a mysql database, displaying table content and so on. Simply put, like a CRM I guess.
I may be way off base here, but I want to be able to create my sql calls as functions, which will help if/when I tweak and tune, as well as creating a cleaner code for what I'm looking to do.
So, without further ado, I have this as a demomstration:
echo "<table>";
selectall('actions','content',$mysqli);
echo "</table><br><br>";
What this does is show all rows from my table of 'actions. "content" is just an example field name I'm passing through that I want to display, as it is the main human-relevant field name in that table. I'm also passing $mysqli through here for my function db call.
My function looks like this:
function selectall($s_table,$s_content,$mysqli){
$query = "SELECT * FROM " . $s_table;
$resource = $mysqli->query($query);
if ( !$resource ) throw new Exception($db->error);
while ( $row = $resource->fetch_assoc() ) {
$id = $row['id'];
echo "<tr><td>{$row[$s_content]}</td></tr>";
}
$resource->free();
$mysqli->close();
}
However.... it doesn't work, and it seems to throw a wobbly saying:
Warning: mysqli::query(): Couldn't fetch mysqli
This points to the action within the line $resource = $mysqli->query($query);
I know the function and everything is ok, as if I restate and declare $mysqli within the first line of the function, like so...
$mysqli = new mysqli(username password and so on in here);
... it works spot on.
$mysqli exists and works within the same code that is passing the variable within the function too.
This is early stages, so by shuffling the code around trying to poke the $mysqli pass into life I have perhaps made the code a little messier that intended, so try not to worry too much about that.
Anyone any ideas why it doesn't like this?
D'oh...
I had a
$mysqli->close();
in the lines above. Solved myself.
For reference, this is my function:
function selectall($s_table,$s_field,$mysqli){
if ($mysqli->connect_error) {die('Connect Error (' . $mysqli->connect_errno . ') '. $mysqli->connect_error);}
$s_table = preg_replace('/[^0-9a-zA-Z_]/', '', $s_table); // Cleans up the table name variable
$s_field = preg_replace('/[^0-9a-zA-Z_]/', '', $s_field); // Cleans up the field name variable
$query = "SELECT * FROM " . $s_table; // Adds passed table name to the select all
$resource = $mysqli->query($query);
if ( !$resource ) throw new Exception($db->error);
while ( $row = $resource->fetch_assoc() ) {
echo "<tr><td>{$row[$s_field]}</td></tr>"; // Content for each row of the select all
}
$resource->free();
$mysqli->close();
}
As you can see, I've also tried to protect the variables that enter the function.
This can be called via:
selectall('actions','content',$mysqli);
In this context, I want to view all the entries in the 'actions' table by the field name 'content'. This function, with some code above and below for a table, will create a new row for each entry.
I'll probably evolve a few, already created on that includes a delete button at the end of the line which is 'selectalldel'.
Open to comments on whether this actually is worthwhile, but thought I'd post up my corrected stupidity in case anyone finds this useful.

Perl DBI modifying Oracle database by creating a VIEW

I wrote a Perl script to check the data in an Oracle database. Because the query process is very complex I chose to create a VIEW in the middle. Using this view the code could be largely simplified.
The Perl code run well when I used it to query the database starting from a file, like Perl mycode.pl file_a. The Perl code reads lines from file_a and creates/updates the view until the end of the input. The results I achieved are completely right.
The problem came when I simultaneously run
perl mycode.pl file_a
and
perl mycode.pl file_b
to access the same database. According to my observation, the VIEW used by the first process will be modified by the second process. These two processes were intertwined on the same view.
Is there any suggestion to make these two processes not conflict with one another?
The Perl code for querying database is normally like this, but the details in each real query is more complex.
my ($gcsta,$gcsto,$cms) = #t; #(details of #t is read from a line in file a or b)
my $VIEWSS = 'CREATE OR REPLACE VIEW VIEWSS AS SELECT ID,GSTA,GSTO,GWTA FROM TABLEA WHERE GSTA='.$gcsta.' AND GSTO='.$gcsto.' AND CMS='.$cms;
my $querying = q{ SELECT COUNT(*) FROM VIEWSS WHERE VIEWSS.ID=1};
my $inner_sth = $dbh->prepare($VIEWSS);
my $inner_rv = $inner_sth->execute();
$inner_sth = $dbh->prepare($querying);
$inner_rv = $inner_sth->execute();
You must
Create the view only once, and use it everywhere
Use placeholders in your SQL statements, and pass the actual parameters with the call to execute
Is this the full extent of your SQL? Probably not, but if so it really is fairly simple.
Take a look at this refactoring for some ideas. Note that is uses a here document to express the SQL. The END_SQL marker for the end of the text must have no whitespace before or after it.
If your requirement is more complex than this then please describe it to us so that we can better help you
my $stmt = $dbh->prepare(<<'END_SQL');
SELECT count(*)
FROM tablea
WHERE gsta = ? AND gsto = ? AND cms= ? AND id = 1
END_SQL
my $rv = $stmt->execute($gcsta, $gcsto, $cms);
If you must use a view then you should use placeholders in the CREATE VIEW as before, and make every set of changes into a transaction so that other processes can't interfere. This involves disabling AutoCommit when you create the database handle $dbh and adding a call to $dbh->commit when all the steps are complete
use strict;
use warnings;
use DBI;
my $dbh = DBI->connect('dbi:Oracle:mydbase', 'user', 'pass',
{ AutoCommit => 0, RaiseError => 1 } );
my $make_view = $dbh->prepare(<<'END_SQL');
CREATE OR REPLACE VIEW viewss AS
SELECT id, gsta, gsto, gwta
FROM tablea
WHERE gsta = ? AND gsto = ? AND cms= ? AND id = 1
END_SQL
my $get_count = $dbh->prepare(<<'END_SQL');
SELECT count(*)
FROM viewss
WHERE id = 1
END_SQL
while (<>) {
my ($gcsta, $gcsto, $cms) = split;
my $rv = $make_view->execute($gcsta, $gcsto, $cms);
$rv = $get_count->execute;
my ($count) = $get_count->fetchrow_array;
$dbh->commit;
}
Is the view going to be the same or different?
If the views are all the same then create it only once, or check if it exists with the all_views table : http://docs.oracle.com/cd/B12037_01/server.101/b10755/statviews_1202.htm#i1593583
You can easily create a view including your pid with the $$ variable to be the pid, but it wont be unique across computers, oracle has also some unique ids, see http://docs.oracle.com/cd/B14117_01/server.101/b10759/functions150.htm, for example, the SESSIONID.
But do you really need to do this? why dont you prepare a statement and then execute it? http://search.cpan.org/dist/DBI/DBI.pm#prepare
thanks,
mike

Django: copy data from one database to another

I have two sqlite.db files. I'd like to copy the contents of one column in a table of on db file to another.
for example:
I have the model Information in db file called new.db:
class Information(models.Model):
info_id = models.AutoField(primary_key = True)
info_name = models.CharField( max_length = 50)
and the following information model in db file called old.db:
class Information(models.Model):
info_id = models.AutoField(primary_key = True)
info_type = models.CharField(max_length = 50)
info_name = models.CharField( max_length = 50)
I'd like to copy all the data in column info_id and info_name from old.db to info_id and info_name in new.db.
I was thinking something like:
manage.py dbshell
then
INSERT INTO "new.Information" ("info_id", "info_name")
SELECT "info_id", "info_name"
FROM "old.Information";
This doesn't seem to be working. It says new.Information table does not exist... any ideas?
You'd need to switch your database URL in your settings file to db2 and run syncdb to create the new tables. After that the easiest thing to do imo would be to switch back to db1 and run ./manage.py dumpdata myapp > data.json, followed by another switch to db2 where you can run ./manage.py loaddata data.json.
Afterwards, you can drop the data you don't need from db2.
Edit: Another approach would be to use the ATTACH function from sqlite. First, I recommend you do the first step above (change database settings and use syncdb to create the tables), then you can switch back and do this:
./manage.py dbshell
> ATTACH DATABASE 'new.db' AS newdb;
> INSERT INTO newdb.Information SELECT * FROM Information;
The dumped file from old.db contains info_type field which is not in the new Information model. This will fail the loaddata which checks all field loaded from JSON file. You could comment out info_type line before dump from old model.
The Attach way mentioned by Alex is easier and great, which needs a tiny tweak
INSERT INTO newdb.Information SELECT * FROM Information;
note the missing parentheses around the SELECT, sqlite does not accept them. Refs http://sqlite.org/lang_insert.html
If you are performing migration, have you tried South