Is there a way to retrieve data from MySQL to Prolog knowledge base?
I am trying to retrieve, for example, the fields: Name and price from a table chair in a MySQL database to a Prolog knowledge base rather than declaring them in Prolog.
The comment by #Boris is interesting. Assuming available a builtin that issues a shell command and get the output stream (in SWI-Prolog we can use library(process)), here is a simple interface to query a Wordpress table from MySQL
query(USER, PWD, DB, QUERY, Columns, Rows) :-
atom_concat('-p', PWD, PPWD),
process_create(path(mysql), ['-u', USER, PPWD, '-D', DB, '-e', QUERY], [stdout(pipe(Out)),stderr(std)]),
read_record(Out, Columns),
read_records(Out, Rows).
read_record(Out, Fields) :-
read_line_to_codes(Out, Codes),
Codes \= end_of_file,
atom_codes(Line, Codes),
atomic_list_concat(Fields, '\t', Line).
read_records(Out, [Record|Rs]) :-
read_record(Out, Record),
!, read_records(Out, Rs).
read_records(Out, []) :-
close(Out).
test run:
test_query :-
query('------','-----',a_blog,"select * from wp_options limit 10", Cols,Rows),
writeln(columns:Cols),
maplist(writeln, Rows).
yields
?- test_query.
columns:[option_id,option_name,option_value,autoload]
[1,siteurl,http://localhost/a_blog,yes]
[2,home,http://localhost/a_blog,yes]
[3,blogname,a blog,yes]
[4,blogdescription,Just another WordPress site,yes]
[5,users_can_register,0,yes]
...
true.
so, instead of display, just assert the records:
capture_table(USER, PWD, DB, QUERY, Functor) :-
query(USER, PWD, DB, QUERY, _Columns, Rows),
maplist(capture_table(Functor), Rows).
capture_table(Functor, Row) :-
Clause =.. [Functor|Row],
assertz(Clause).
Related
I am using an MVC framework (Zend) for my application and I want to find the total size of a table in PostgreSQL (including index). The table name is "V5TableName" - quotes included because table name is case sensitive. I have made sure that there is NO typo involved.
My code to get the table size is shown below:
public function getMyTableSize()
{
$sql = "SELECT pg_size_pretty(pg_total_relation_size( '\"V5TableName\"' ) );";
/* Custom_Db is a custom library in my application which makes the PostgreSQL connection
and queries the database
*/
$tableSize = Custom_Db::query($sql)->fetchColumn();
return $tableSize;
}
When my application calls this function it returns the following error in my logs :
[22-Apr-2020 09:42:37] PID:30849 ERR: SQLSTATE[42P01]: Undefined table: 7 ERROR: relation "V5TableName" does not exist
LINE 1: SELECT pg_size_pretty(pg_total_relation_size( '"V5TableName...
^
query was: SELECT pg_size_pretty(pg_total_relation_size( '"V5TableName"' ) );
If I run this same query in pgAdmin4 it works perfectly fine returning the table size (for instance: 104Mb).
I have tried:
Removing and adding quotes to the table name in the code.
Appending the schema as prefix to the table name (example: 'public."V5TableName"').
NONE of the above seem to work. I am not sure what is going wrong over here.
I also tried to find the total database size in my application (db name: MyDbName - with mixed case spelling) and my query looked something like below:
$sql = "SELECT pg_size_pretty(pg_database_size('MyDbName'))"; // this DID NOT WORK
So I changed it to the one shown below: (it worked)
$sql = "SELECT pg_size_pretty(pg_database_size( current_database() ))"; // this WORKED
I was wondering if there is something similar that could be done to find the table size.
Your query should work. The use of double-quotes seems correct.
SELECT pg_size_pretty(pg_total_relation_size('"V5TableName"'));
First make sure you are connecting to the right database cluster (a.k.a. "server"). It's defined by its data directory, or equally unambiguous by hostname and port number. Read the manual here and here.
Then make sure you are connecting to the right database within that database cluster. A Postgres database cluster consists of 1-n databases. When connecting without specifying the actual database, you end up in the maintenance database named postgres by default. That's the most likely explanation. Check with:
SELECT current_database();
Then check for the right table and schema name:
SELECT * FROM pg_tables
WHERE tablename ~* 'V5TableName'; -- ~* matches case-insensitive
The first riddle should be solved at this point.
Check your DB spelling and possible near-duplicates with:
SELECT datname FROM pg_database;
The call is without double-quotes (like you tried correctly), but requires correct capitalization:
SELECT pg_size_pretty(pg_database_size('MyDbName'));
Note the subtle difference (as documented in the manual):
pg_database_size() takes oid or name. So pass the case-sensitive database name without double-quotes.
pg_total_relation_size() takes regclass. So pass the case-sensitive relation name with double-quotes if you need to preserve capitalization.
pg_database_size() has to differ because there is no dedicated object identifier type for databases (no regdatabase).
The gist of it: avoid double-quoted identifiers in Postgres if at all possible. It makes your life easier.
I have 2 separate and different databases:
SOURCE_DATABASE
TARGET_DATABASE
I am trying to copy a table from SOURCE_DATABASE to TARGET_DATABASE using PHP and not phpMyAdmin (as it works fine in phpMyAdmin).
I have the following php:
$linkSource = mysql_connect( SERVER, SOURCE_USERNAME, SOURCE_PASSWORD );
mysql_select_db( SOURCE_DATABASE, $linkSource );
$linkTarget = mysql_connect( SERVER, TARGET_USERNAME, TARGET_PASSWORD );
mysql_select_db( TARGET_DATABASE, $linkTarget );
mysql_query( 'CREATE TABLE `targetDB.targetTable` LIKE `sourceDB.sourceTable` ) or die( mysql_error() );
Is it possible to create a table in a 2nd database (target) using the structure of a table in a 1st database (source)?
PhpMyAdmin and PHP is wrong tools for this purposes. Use command line shell. Something like this:
mysqldump -u root -p database1 > database1.sql
mysql -u root -p database < database1.sql
It will work in 10 times more faster, I'm guarantee it. Also, database will take care about data consistency instead of you.
If you are realy want to do it in PHP, use php command line shell.
If you are still want to do it in PHP WITHOUT command line shell, I can suggest to do this kind of trick:
$query = "show tables from source_database";
$tables = $dbSource->getColumn($query)//get one column from database
foreach($tables as $tableName) {
$query = "show create table ".$tableName;//← it will return query to clone table structure
$createTableSchema = $dbSource->getRow($query);//← get assoc array of one row
$dbTarget->query($createTableSchema['Create Table']);//← here is your silver bullet
}
PS and also, when (if) you will copy data from one table to another table, you should know that statement
insert into table () values (values1), (values2), (values3);
much more faster than
insert into table () values (values1);
insert into table () values (values2);
insert into table () values (values3);
But insert multy rows is related to max_allowed_packet propery field. In case, when your query will more large than this field (yes, query string can allocate 1 gb of memory), MySQL will throw exception. So, to build Insert multy query you should get max_allowed_packet and generate this query according to this size. Also to speed up performance you can disable keys from target table. (do not forgot to enable keys, lol)
You could use MySQL's "SHOW CREATE TABLE" function to get the structure of the source table, and then execute the CREATE TABLE statement it gives you in the target connection.
$result = mysql_query("SHOW CREATE TABLE sourceTable", $linkSource);
$create_table = mysql_result($result, 0, 1);
mysql_query($create_table, $linkTarget);
I have a weird problem for some of my rows in a specific column.
The column is named description and there are a number of entries.
When performing a query from php, I can get all of them except one (php return NULL).
In my phpmyAdmin the data for that specific is this:
μαλλον θα Ï€Ïεπει να κανουμε υπομονη μεχÏι τη δευτεÏα Ï€Î
and the structure for that column is : varchar(200), utf-general-ci
I know that this entry is Greek. But there are other Greek entries, which are visible.
My php code is this:
for quering:
$query="SELECT description,date FROM allComments p JOIN login l ON (p.IdUser=l.IdUser) WHERE p.IdPhoto=$photo";
and for inserting data:
$query2="INSERT INTO allComments (IdPhoto,IdUser,description,dates) VALUES($photoId,$id,'$text','$date')";
What do you think might be the problem?
The entry is made correctly, since all the other columns (date for example are retrieved correctly - only this column is null)
Try to set Encoding in mysqli.
mysqli_set_charset($link, "utf8");
PHP Documentation
I would expect the following to output the number "5", since there are 5 rows in the database with with item 68 and user 1. But instead I'm getting this output "12345".
$resultb4 = mysql_query("SELECT COUNT(comparedRating) FROM recComparedRating WHERE user1='1' AND itemID='68' GROUP BY itemID AND user1");
while($rowb4 = mysql_fetch_array($resultb4)){
$countcomparedratings=$rowb4['COUNT(comparedRating)'];
}
echo $countcomparedratings;
What am I doing wrong?
The reason you are getting 12345 is because your query is returning 5 results and your code to output the count is simply outputting the concatenation of the returned array from the query.
Without understanding your database structure, I'm guessing that the reason you're getting the '12345' has something to do with your GROUP BY clause. Use a program like MySQLWOrkbench to connect to your database and test out your query before you include it into your code. It is a time saving technique to debug your queries.
Also, I would alias the COUNT value so that you simply refer to the alias when you refer to your column names.
SELECT COUNT(comparedRating) as ratingCount FROM recComparedRating WHERE user1='1' AND itemID='68' GROUP BY itemID AND user1");
I created a column family Users using following command:
create column family Users with comparator=TimeUUIDType and default_validation_class=UTF8Type;
Then I insert a column into Users. It shows as follows.
RowKey: jsmith
=>(column=66829930-515b-11e0-8443-0f82b246fa40, value=hello, timestamp=1300451382)
I want to access it using SimpleCassie. The command is:
$data = $cassie->keyspace('Keyspace1')->cf('Users')->key('jsmith')->column('66829930-515b-11e0-8443-0f82b246fa40')->value();
(I also tried: $data = $cassie->keyspace('Keyspace1')->cf('Users')->key('jsmith')->column($cassie->uuid('66829930-515b-11e0-8443-0f82b246fa40')->__toString())->value();)
However, They do not work. It always return NULL.
How can I get the column value (hello) I want?
Try:
$cassie->keyspace('Keyspace1')->cf('Users')->key('jsmith')->column($cassie->uuid('66829930-515b-11e0-8443-0f82b246fa40')->uuid)->value();)
Cassandra expects the binary representation of a UUID, not a hex/string representation.