.schema for postgres - sqlite

I'm migrating a database from sqlite3 to postgres and am wondering if there are any short tutorials that can teach me the new syntax.
Also, as a short term question, how do I see the schema of a postgres table which is equivalent to .schema in sqlite?

You could use pg_dump command line utility, i.e.:
pg_dump --table <table_name> --schema-only <database_name>
Depending on your environment you probably need to specify connection options (-h, -p, -U switches).

You could use \d from within psql:
=> \?
...
Informational
(options: S = show system objects, + = additional detail)
\d[S+] list tables, views, and sequences
\d[S+] NAME describe table, view, sequence, or index
...
=> \d people
Table "public.people"
Column | Type | Modifiers
------------------------+-----------------------------+-----------------------------------------------------
id | integer | not null default nextval('people_id_seq'::regclass)
created_at | timestamp without time zone | not null
updated_at | timestamp without time zone | not null
...
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
...
Check constraints:
"chk_people_latlng" CHECK ((lat IS NULL) = (lng IS NULL))
....
You can also root around in the information_schema if you're not inside psql.

If you are using psql (and \d... ) then you can
\set ECHO_HIDDEN
to see the sql for the queries that psql is executing to put together the \d... output-- this is useful not only as sql syntax examples but it also shows you where find, and how to connect, the database metadata.
To get the schema name for a table you can:
SELECT n.nspname AS schema_name,
c.relname AS table_name
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname = '<table_name>'
;
(don't know how that compares to .schema)

Maybe you can use a PostgreSQL Cheat Sheet:
http://www.postgresonline.com/special_feature.php?sf_name=postgresql83_cheatsheet&outputformat=html

Related

Get creation timestamp in row metadata in ADX

Is there a function or command that provides the row creation timestamp thru metadata in ADX?
TIA
ingestion_time()
Returns the approximate time at which the current record was ingested.
This function must be used in the context of a table of ingested data for which the IngestionTime policy was enabled when the data was ingested. Otherwise, this function produces null values.
In case anyone wants the commands exactly:
.alter table TableName policy ingestiontime true
Then to view the times:
TableName
| extend ingestion_time()
| sort by ingestion_time()
Replace TableName with your table name, hope this helped!

How to update an existing tables datetime column with current datetime in sqlite

I have an existing sqlite database with a table in it something like this:
+------+----------+--------------------+----------------+
|LogID | UsedOn | UserID | Other fields() |
+------+----------+--------------------+----------------+
| 1 | | soemid03 | SomeDataHere |
+------+----------+--------------------+----------------+
Etc....
The UsedOn field is currently blank, because when I made the table I accidently forgot to set the field type to a timestamp type, so the application was just inserting the other colums and leaving this one blank.
Because I would like to use a comparison at some point later using the timestamp, I would like to update this column for all rows in the table with the current timestamp, I assume I can use datetime() in sqlite to do this. It does not matter too much that some of the dates and times will be out by a few days, but the field cannot be empty or my comparison code would not work.
I tried using:
UPDATE tablename SET UsedOn=datetime()
And this was accepted as a valid query, but it seems to do nothing, this column is still empty.
perhaps I'm doing this wrong in some way?
I can only edit the database/table via either manual queries or by using 'SQLite Administrator' app (from http://sqliteadmin.orbmu2k.de/). I can't use anything else because that is what is available and I'm not allowed to install any other database management tools. When I try to edit any row in the table to add a datetime manually, it does not get accepted, but I just assume this is because the app is trying to insert what I type as a string (even though the format is correct) and it's not a string field type.
I tried your code in SQLite Administrator and it does not work, while it should.
What does work is:
UPDATE tablename
SET UsedOn = CURRENT_TIMESTAMP
This does not mean that your code is wrong.
If you use any other tool like DB Browser for SQLite, both solutions would work.

Dump SQLite table/DB without auto-generated columns (e.g id)

I have an SQLite 3 database (db) like in this simplified example:
CREATE TABLE user(id integer primary key, name text);
INSERT INTO "user" VALUES(1,'user1');
INSERT INTO "user" VALUES(2,'user2');
If I enter .dump, sqlite will wrap these statements in a transaction and write them to the file db.sql previously defined with .output. This is fine if I need to import the data to an empty DB.
I want to be able to import the user data to a different DB with other users defined. If I try, I will most likely get something like this (as the ids may be used already in the target DB):
Error: near line 4: PRIMARY KEY must be unique
Error: near line 5: PRIMARY KEY must be unique
My approaches:
I can tweak the dumped SQL manually to remove everything but the inserts and also remove the id column (mentioning only name) in the statement, but this approach does not scale as I want to automate the process.
I can select from the db and write the SQL myself.
Is there any easy or more elegant approach that I am missing? sqlite3 will be run from a Bash script in the real world problem.
You can automate the tweaking (but this still requires that you know the table structure):
$ (echo ".mode insert"; echo "SELECT name FROM user;") | \
sqlite3 my.db | \
sed -e 's/^INSERT INTO table /INSERT INTO user(name) /'
INSERT INTO user(name) VALUES('user1');
INSERT INTO user(name) VALUES('user2');

Postgres: org.postgresql.util.PSQLException: ERROR: insufficient data left in message

I read enough to know that this occurs when a string contains some characters that Postgres doesn't like. However, I cannot figure out if there is a way to validate strings before writing them. In particular, I'm doing batch inserts.
insert into foo(col1,col2,col3) values ('a',2,3),('b',4,0),....
My DB is setup like this:
Name | Owner | Encoding | Collate | Ctype | Access privileges
------------+--------+----------+---------+-------+-------------------
stats | me | UTF8 | C | C |
Periodically, some bad string will get in and the whole insert will fail(e.g. change���=). I batch up quite a few values in a single insert so I'd like to ideally validate the string rather than bomb the whole insert. Is there a list of which characters are not allowed in a Postgres insert?
Using postgresql-jdbc 9.1-901.jdbc4
This message means that your string data has a null character "\0" in it.
I can't find an authoritative cite for this (let me know if you have one).
It is discussed at https://www.postgresql.org/message-id/alpine.BSO.2.00.0906031639270.2432%40leary.csoft.net
It is mentioned in passing in the official docs at https://www.postgresql.org/docs/9.3/static/functions-string.html
All other characters are allowed.
date type is not match target type.for example int4->int8
On my case, I was loading query from an sql file. The problem was due to the encoding.
I change it to UTF-8 and it works. Hope that helps !

How could you get if a table is autoincrement or not from the metadata of an sqlite table?

In case you have several tables inside any sqlite database how could the get the information that they have an auto increment primary key or not?
For instance I am already aware that you could get some info concerning the columns of a table by simply querying this: pragma table_info(tablename_in_here)
It would be much better to get the auto increment column dynamically rather than setting up each corresponding model inside the source code with a boolean value.
Edit:
Let me use this table as an example:
CREATE TABLE "test" (
"id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
"name" TEXT NOT NULL
)
and this is the result table after executing pragma table_info("test")
cid | name | type | notnull | dflt_value | pk
0 | id | INTEGER | 1 | null | 1
1 | name | TEXT | 1 | null | 0
As you can see there is no information whether the id column is autoincrement or not
Edit2:
I looking for a solution that involves sqlite directly through a statement.
Special situations where the sqlite3 command in the terminal can be used to somehow parse the required information from inside are not acceptable. They do not work in situations where you are not allowed to execute commands in a terminal programmatically. Like in an Android app.
Autoincrementing primary keys must be declared as INTEGER PRIMARY KEY or some equivalent, so you can use the table_info date to detect them.
A column is an INTEGER PRIMARY KEY column if, in the PRAGMA table_info output,
the type is integer or INTEGER or any other case-insensitive variant; and
pk is set; and
pk is not set for any other column.
To check whether the column definition includes the AUTOINCREMENT keyword, you have to look directly into the sqlite_master table; SQLite has no other mechanism to access this information.
If this query returns a record, you have the AUTOINCREMENT keyword somewhere in the table definition (which might return a wrong result if this word is commented out):
SELECT 1
FROM sqlite_master
WHERE type = 'table'
AND name = 'tablename_in_here'
AND sql LIKE '%AUTOINCREMENT%'
You can parse the output of .schema. That will give you the sql commands as you used them to create your tables. If autoincrement was declared, you will see it in the output. This has the advantage that it will list all your tables too.

Resources